A note’s identity should outlive its wording
How stable IDs and a build baseline work together when you update a generated Anki deck.
Read articleTurn knowledge into Anki decks with Rust. Write your notes, add media, and keep identities stable as content changes.
let (front, back) = ("hola", "hello");
let mut deck = Deck::new("Spanish");
deck.basic().note(front, back).stable_id("es:hola").add()?;
let report = deck.write_apkg(output.join("spanish.apkg"))?;
report.ensure_success()?;hola
What does this mean?Question shown.
let text = "A sound's pitch depends on its {{c1::frequency}}.";
let extra = "More cycles per second, higher pitch.";
let mut project = Project::new("Sound")
.stable_id("website-sound")
.default_deck("Sound");
project.add_note(Note::cloze(text).extra(extra).stable_id("sound:pitch"))?;
let report = project.write_apkg(output.join("sound.apkg"))?;
report.ensure_success()?;A sound's pitch depends on its […].
Question shown.
let (prompt, answer) = ("Name this pitch.", "A4, 440 Hz");
let picture = project
.media_mut()
.add_file(output.join("waveform.svg"))?
.export_as("waveform.svg")?;
let audio = project
.media_mut()
.add_file(output.join("concert-a.wav"))?
.export_as("concert-a.wav")?;
project.add_note(
Note::new("ear-training")
.stable_id("sound:a4")
.text("prompt", prompt)
.text("answer", answer)
.image("picture", picture)
.sound("audio", audio),
)?;
let report = project.write_apkg(output.join("ear-training.apkg"))?;
report.ensure_success()?;Name this pitch.
Question shown.
Real code. Downloadable decks. A simplified preview of the cards inside.
Correct a definition or add an example. Stable IDs and a previous build help Anki Forge match existing notes when you export again.
Understand deck updateses:holahola
hello
Try a content change.
Inspect diagnostics for missing fields, media, and template problems. Make validation part of your build.
Explore validationStart with Basic and Cloze, or define your own note types. Keep HTML, CSS, and media in reusable template bundles.
Explore templatesRun the smallest example from the source checkout, then open spanish.apkg in Anki. Requires Rust 1.92 or later.
git clone https://github.com/morehardy/anki-forge.git
cd anki-forge
cargo run -q -p anki_forge --example target_api_basicHow stable IDs and a build baseline work together when you update a generated Anki deck.
Read articleFrom a short Rust program to a Spanish flashcard you can open in Anki.
Read article