Third-Party Notices — Coii Ref
Effective 2026-09-19
Coii Ref is built on open-source software and runs a machine-learning model it did not train. This file lists them, states the licence each is under, and says what that licence requires of a paid product.
This document is the readable summary. The authoritative list ships with the app, as
licenses/THIRD-PARTY-LICENSES.txt, embedded in the binary and served at/legal/third-party-licenses. That one is generated from the actual dependency tree — several hundred crates once transitive ones are counted — while §2 below names only the direct dependencies, in the interest of being read. Where the two disagree, the generated file is right. How it is produced and kept current:docs/releasing.mdin the Coii Ref repository.
1. Can a paid app be built on all of this?
Yes, and the answer divides in two.
Most of what is listed below is under MIT, Apache-2.0, BSD, ISC, CC0, the public domain or MPL-2.0. Every one of those permits commercial use, selling and distribution in a closed-source product, and what they nearly all ask in return is attribution: the copyright line and the licence text have to travel with the binary, which they do — see §4.
Four components are under the LGPL, which is a weaker copyleft than its name suggests. It permits a proprietary program to use the library and does not ask us to publish our own source. What it asks instead is in its §6: someone who has the binary must be able to replace that library with their own build and still have a working program. Which four, and what each one costs, is §1.1 below.
No GPL or AGPL component is present. That is the licence that would reach our
own source, and staying behind that line is a build decision rather than a happy
accident — see the ffmpeg configure line in §1.1 and the about.toml guard in
docs/releasing.md, which fails generation rather than let a GPL dependency
arrive quietly.
The one licence that asks for more is MPL-2.0, on two crates that were never
chosen directly: option-ext, which arrives through dirs, and colored, which
arrives through hf-hub's xet-runtime. MPL is copyleft per file, not per
program, and explicitly permits combination with proprietary code, so no part of
this app falls under it. Its §3.2 asks that anyone receiving the binary can
obtain the source of those files; they are used unmodified, so the generated
notices file points at crates.io for each. Vendoring a patched copy of one of
them would change that, and is the thing to avoid.
1.1 The LGPL components
| component | licence | how it reaches you |
|---|---|---|
FFmpeg — the coii-ffmpeg and coii-ffprobe sidecars |
LGPL-2.1-or-later | two separate executables inside the bundle, beside the app's own |
| libheif | LGPL-3.0 | linked into coii-serve, statically on macOS |
| libde265 | LGPL-3.0 | the HEVC decoder libheif calls, likewise |
rawler |
LGPL-2.1 | the camera-raw decoder, a Rust crate, statically linked |
ffmpeg is here, and it is here in a specific configuration. The app this one
replaces bundled two stock ffmpeg binaries at 158 MB each and used them for
everything — HEIC, camera raw and video. Most of that is now delegated to tools
macOS already ships (sips, qlmanage, mdls); crates/assets/src/delegated.rs
gives the engineering reasons. What is left for ffmpeg is rendering a poster
frame out of a video, and the sidecars that do it are built from source by
scripts/build-ffmpeg.sh rather than downloaded — about 12 MB each.
That build is the licensing decision. ffmpeg is LGPL-2.1-or-later by default and
becomes GPL as soon as it is configured with certain external libraries — x264
and x265 are encoders, and --enable-gpl exists to let you link them. This build
enables no external library at all and passes --disable-autodetect so it cannot
quietly find one on the machine that compiles it, which leaves plain LGPL ffmpeg
with no argument to have. Nothing the app needs lives behind that flag: the
H.264, HEVC, VP9 and AV1 decoders are core code. BUILD-INFO.txt, written by
the same script, records the version, the source URL and the exact configure
line, so the binary can always be traced to what produced it.
What §6 asks, and how each of these answers it. The ffmpeg sidecars are the
easy case: they are separate executables invoked by filename, so replacing one
with your own build is copying a file over it, and nothing further is owed.
libheif, libde265 and rawler are linked into coii-serve, and a static link
satisfies §6 only by making the object files needed to relink available. Write
to support@coii.io and we will send you them, for the release you have, along
with the source and build configuration of each library.
Apple's own decoders — used through ImageIO and AVFoundation — are covered by the SDK licence that comes with Xcode, are linked rather than redistributed, and raise none of this.
2. Components compiled into the app
Shipped inside the binary, so their notices must travel with it. Direct dependencies only; the generated file has the whole tree.
| component | licence | role |
|---|---|---|
SQLite, via rusqlite |
public domain (SQLite); MIT (rusqlite, libsqlite3-sys) |
the index, one database per workspace |
candle — candle-core, candle-nn, candle-transformers, and the Metal kernels |
MIT OR Apache-2.0 | runs the semantic-search model, on Metal where there is a GPU |
tokenizers |
Apache-2.0 | turns a search phrase into tokens the model reads |
Oniguruma, via onig |
BSD-2-Clause (the C library); MIT (onig, onig_sys) |
the regular-expression engine inside tokenizers |
hf-hub |
Apache-2.0 | downloads the model files |
image, imagesize, infer |
MIT OR Apache-2.0 (image); MIT (the others) |
in-process decoding, dimensions and format sniffing |
libheif and libde265, via libheif-rs |
LGPL-3.0 (both C/C++ libraries); MIT (libheif-rs) |
decodes HEIC, HEIF and AVIF — the format a modern iPhone photograph arrives in. See §1.1 |
rawler |
LGPL-2.1 | decodes camera raw. See §1.1 |
kamadak-exif |
BSD-2-Clause | EXIF facts |
jwalk, rayon |
MIT (jwalk); MIT OR Apache-2.0 (rayon) |
the parallel scan |
notify, notify-debouncer-full |
CC0-1.0 (notify); MIT OR Apache-2.0 (the debouncer) |
the filesystem watcher |
axum, tower-http, tokio, tokio-stream, mime_guess |
MIT | the local HTTP service |
tauri, tauri-plugin-single-instance, tauri-plugin-updater, tauri-plugin-dialog, and the wry, tao and muda they are built on |
Apache-2.0 OR MIT | the window, its menu bar, the WebKit view inside it, and the update check — see crates/shell. Those three were taken directly until 2026-09-19; the app now uses them through Tauri, which is the same code one level up |
reqwest with rustls |
MIT OR Apache-2.0 (reqwest); Apache-2.0 OR ISC OR MIT (rustls) |
the two licensing calls and the trusted-time request |
keyring-core, apple-native-keyring-store |
MIT OR Apache-2.0 | the copy of the licence state in the macOS keychain |
serde, serde_json, thiserror, tracing, tracing-subscriber, parking_lot, crossbeam-channel, getrandom, sysinfo, tempfile, async-trait |
MIT or MIT OR Apache-2.0 | general utilities |
Shipped beside the binary rather than inside it
One entry does not belong in the table above, and is owed the same notice anyway:
the ffmpeg sidecars, coii-ffmpeg and coii-ffprobe (LGPL-2.1-or-later),
which sit in Contents/MacOS/ next to the app's own executables and render the
poster frame for a video. What a notices file owes is decided by what is
distributed, not by what is linked, so they are listed here, in the generated
file, and in §1.1 — where the configure line they were
built with is the reason they are LGPL and not GPL.
Apple's own tools and frameworks — sips, qlmanage, mdls, ImageIO,
AVFoundation, Metal, Security, AppKit and WebKit — are used under the Apple SDK
licence that comes with Xcode, and are not redistributed. The window is a
WKWebView: macOS's own browser engine, linked rather than shipped, which is why
no browser appears in the table above.
No npm packages ship. The only web asset in the app is
crates/serve/web/index.html, which is hand-written, has no dependencies and no
build step. The generated notices file therefore has no JavaScript section, and
scripts/gen-licenses.sh fails the day a package.json appears rather than
quietly ceasing to be the whole answer.
3. The model, downloaded at runtime
Not bundled. The app fetches it onto your machine only if you install semantic search, and it is licensed by whoever trained it.
| model | source | licence |
|---|---|---|
SigLIP base, patch16, 224px (model.safetensors + tokenizer.json, ~815 MB) |
huggingface.co/google/siglip-base-patch16-224 |
Apache-2.0 (the model card is the authority — re-check it at release) |
Two things were checked before this one was picked, and they are the bar anything replacing it has to clear:
- The weights' licence, not the repository's. A permissive repository can publish weights under a bespoke community licence with a prohibited-use policy attached. Those are not open source, and a pass-through obligation the app has nowhere to perform is a reason to choose a different model rather than a screen to design. SigLIP's weights are Apache-2.0, which asks for attribution and nothing else.
- What the weights were trained on. A model trained on a research-only dataset raises a question about commercial use that is genuinely unsettled and differs by jurisdiction, and an unsettled question is not a licence. SigLIP was trained by Google on WebLI, published under a licence with no field-of-use restriction, which is the answer this app needs.
The app never redistributes the weights: the user's machine fetches them from Hugging Face, and uninstalling the component deletes them again.
Not a licence question, but adjacent
Hugging Face is not obliged to keep serving us. It can rate-limit, move or withdraw a file, and an install that depends on it will fail when it does. §11 of the Terms says so to the buyer, and the app is built so that this costs a feature rather than the product: semantic search is a component, and everything else works without it.
4. How the notices are actually delivered
MIT, Apache-2.0, BSD and ISC all require the copyright notice and licence text to
be distributed with the binary. The condition is on the copy — MIT says the
notice "shall be included in all copies", and Apache-2.0 §4(a) says recipients
must be given a copy of the licence — so a link to a web page does not satisfy
it. Apache-2.0 §4(d) even enumerates the three acceptable places for a NOTICE
file's contents: a NOTICE text file in the distribution, the documentation
shipped with it, or a display the software itself generates. A URL is not among
them.
So the notices travel with the app:
| The file | licenses/THIRD-PARTY-LICENSES.txt, embedded into coii-serve with include_str! — it is inside the executable, not beside it |
| The display | GET /legal/third-party-licenses, and Settings → About → Legal in the harness page, both reading that same embedded copy |
One copy, so the two can never disagree. The .app bundle
scripts/release.sh builds needs no separate copy as
a resource: coii-serve is inside it, at Contents/MacOS/coii-serve, with the
file embedded — so a bundle that has the server has the notices, and there is no
second artifact to keep in step.
That file is not maintained by hand — scripts/gen-licenses.sh generates it from
the dependency tree the binary is actually built from, and
scripts/gen-licenses.sh --check fails when the committed copy has drifted.
docs/releasing.md in the Coii Ref repository has the mechanics and the reasoning.
5. Contact
Corrections to this file, or a licence claim you believe is wrong, to support@coii.io — they are worth fixing quickly.