Skip to content

Repository files navigation

Quill

A standalone, on-device transcription CLI for macOS. quill transcribe <file> turns a local audio file, or the audio track of an .mp4 or .mov video, into a markdown transcript.

Transcription happens on your machine, through Core ML. Your audio is not sent anywhere. The only network traffic is downloading a model variant you do not have yet; once it is cached, Quill runs with no network connection at all. Pure audio in, markdown out.

Requirements

  • macOS 13 (Ventura) or later.
  • macOS only by design: WhisperKit is Core ML-based.

Building from source, which is how Quill is installed, additionally needs a Swift 6.2 toolchain (Xcode 26). The installed binary does not.

Install

Clone the repository and install a release build:

git clone https://github.com/async-digital-ltd/quill-cli.git
cd quill-cli
make install

make install builds with swift build -c release and copies the binary to /usr/local/bin/quill, which may need sudo. To install somewhere you own instead, set PREFIX; the binary goes to $PREFIX/bin/quill:

make install PREFIX="$HOME/.local"  # installs to ~/.local/bin/quill

Then quill is runnable from any shell that has that directory on its PATH. Remove it with make uninstall, passing the same PREFIX if you set one.

Usage

quill transcribe <file> [--output <path>] [--model <variant>]
  • The transcript is written to standard output as markdown, or to a file with --output <path> (-o).
  • Progress is written to standard error, so quill transcribe clip.m4a > out.md captures only the transcript.
  • Quill reads files through Core Audio. Audio files work (.m4a, .mp3, .wav, .flac, .aiff, …), and so do .mp4 and .mov videos, whose audio track is transcribed. Matroska and WebM (.mkv, .webm) do not open; extract the audio to one of the formats above first.

Examples:

quill transcribe interview.m4a > interview.md
quill transcribe interview.m4a --output interview.md
quill transcribe interview.m4a --model openai_whisper-small

Models

The first run for a given model downloads it from Hugging Face into ~/Library/Application Support/Quill/models/… and reuses it thereafter, with no network connection. Two repositories are involved: argmaxinc/whisperkit-coreml for the Core ML weights, and the matching openai/whisper-* for the tokenizer. Set QUILL_CACHE_DIR to put that cache somewhere else: another volume, or a tree you already back up:

export QUILL_CACHE_DIR="$HOME/caches/quill"

The model and its tokenizer both land under whichever directory is in effect.

Licences: the Core ML models in argmaxinc/whisperkit-coreml are MIT. They are converted from OpenAI's Whisper weights, which Hugging Face lists as Apache-2.0 for openai/whisper-tiny through openai/whisper-large-v3 and MIT for openai/whisper-large-v3-turbo. Downloading from Hugging Face is also subject to Hugging Face's terms of service.

Pick a model with --model (-m); the trade-off is footprint and speed against accuracy:

Variant Size (approx.) Notes
openai_whisper-tiny ~75 MB Fastest, roughest. Good for quick checks.
openai_whisper-base ~145 MB Default. Balanced; comfortable on 16 GB machines.
openai_whisper-small ~500 MB Noticeably more accurate; still light.
openai_whisper-large-v3_turbo ~1.5 GB Most accurate; heaviest.

base is the default because it is the one that behaves on a constrained machine: it stays well within memory on 16 GB and downloads quickly.

It is not the right default for every source. base is more prone to mangling unfamiliar terms and, less often, to inverting meaning on fast speech. For terminology-sensitive or archival work (technical talks, product and brand vocabulary, rapid speakers), pass --model openai_whisper-small or openai_whisper-large-v3_turbo and accept the memory and time cost.

Build from source

swift build
swift test

Every dependency is public, so a clean clone builds with no credentials configured. See CONTRIBUTING.md before opening a pull request, and AGENTS.md for the architecture and conventions.

Privacy

Worth stating plainly, because people transcribe sensitive recordings:

  • Your audio never leaves the machine. Transcription runs on-device through Core ML, and Quill never sends your audio or transcripts over the network.
  • The network is used only to download a model you do not have yet. Each run first checks the cache for the variant named by --model. If a complete copy is there, the run makes no network request of any kind, so it works offline. If not, WhisperKit downloads the Core ML weights from argmaxinc/whisperkit-coreml and, as a separate request, the tokenizer from the matching openai/whisper-* repository, and later runs reuse both. Name the variant in full, as in --model openai_whisper-small: a short name such as --model small is resolved against Hugging Face, so it goes online every time.
  • A Hugging Face token is sent only with a download. WhisperKit's Hugging Face client looks for a token in HF_TOKEN, HUGGING_FACE_HUB_TOKEN, HF_TOKEN_PATH, $HF_HOME/token, ~/.cache/huggingface/token and ~/.huggingface/token, and if it finds one it sends it as an Authorization header on the download requests. The models are public and need no token, so unset it for the first run if you would rather not send it. A run from the cache sends nothing.
  • No telemetry, no analytics, no crash reporting. There is nothing to opt out of.
  • Nothing is retained but downloads. The cache under ~/Library/Application Support/Quill holds model and tokenizer files. During a download, macOS's networking layer also keeps its own HTTP cache of the responses under ~/Library/Caches/quill, outside QUILL_CACHE_DIR. Neither holds audio or transcripts: those go to standard output or to the path you name, and nowhere else.

CLI contract

The command-line surface is documented and covered by semver in docs/cli-contract.md: invocation, streams, markdown format, and exit codes. If you are scripting against quill, that document is the thing to depend on, and changes to it follow semver.

Licence

MIT. See LICENSE.

About

On-device transcription for macOS from the command line. Audio in, markdown out.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages