Back to Research

Simon Willison Ships alchemy-utils Alpha

Simon Willison’s alchemy-utils 0.1a0 turns an AI-built database spike into a small alpha worth studying.

A View on Hampstead Heath with Harrow in the Distance, landscape painting by John Constable (1822).
Rogier MullerAugust 13, 20268 min read

Simon Willison’s alchemy-utils 0.1a0 is an alpha Python library and CLI release for using sqlite-utils-style table operations across multiple database engines. It deals with a question Willison has been circling for a while: what would a database-agnostic version of his sqlite-utils project look like if it were backed by SQLAlchemy? The useful part is not just the package; it is the shape of the AI-built research spike that produced it. alchemy-utils is a Python library and command-line tool that tries to expose familiar insert, upsert, create, update, and introspection methods on top of SQLAlchemy-backed databases.

As of the August 12, 2026 post, Willison says he tasked OpenAI’s Codex and GPT-5.6 Sol Ultra with building the prototype, using his existing sqlite-utils repository as reference material. That makes the release interesting to anyone doing agentic coding, because it shows a small but real example of an AI coding workflow ending in a publishable alpha instead of a half-finished demo.

Read the release as a working receipt

The first thing to notice is how concrete the target was. Willison did not ask for “a database library.” He asked for the same core API as sqlite-utils, with specific methods called out: insert, upsert, insert_all, upsert_all, create, update, and table introspection.

That matters because coding agents are much better when the work has edges. “Make sqlite-utils, but SQLAlchemy-backed, tested against PostgreSQL, SQLite, and DuckDB” gives the agent a map, a reference implementation, and a compatibility check.

The trap is treating the alpha as proof that the broad problem is solved. It is better to read alchemy-utils 0.1a0 as a receipt: a bounded project, a reference repo, a database matrix, tests, and a release marker.

Willison’s example CLI command is refreshingly mundane:

uvx --with 'alchemy-utils[postgresql]' alchemy-utils rows \
  'postgresql+psycopg://simon@localhost:5432/simonwillisonblog' \
  redirects_redirect

That one-liner lists rows from a local PostgreSQL table. Small examples like this are valuable because they force the project to cross the line from “library code exists” to “a developer can run it.”

The prompt had product taste baked in

The most interesting part of the source note is the assignment. It included the package manager (uv init), the development style (“red/green TDD and pytest”), the test targets, and the habit of committing early and often.

That is product taste, not just prompting. It tells the coding agent what finished work should feel like: initialized project, visible history, executable tests, compatibility with real engines, and an API shaped by an existing successful tool.

The trap is copying the exact prompt without copying the constraints. If your repo has no reference implementation, no test harness, and no acceptance examples, “do a research spike” becomes a permission slip for wandering.

A closer Claude Code, Anthropic’s coding agent, version of the same move would be a slash command that starts with the contract, not the implementation:

/agent-spike-db-utils

Goal: prototype a small SQLAlchemy-backed utility with sqlite-utils-like table APIs.
- Read ./vendor/sqlite-utils-notes.md for API shape.
- Preserve method names where practical.

Acceptance checks:
- pytest passes locally.
- Tests cover SQLite and one networked database if available.
- CLI can list rows from a real table.
- Commit after each passing slice.

Stop conditions:
- Do not add migrations, auth, background jobs, or web UI.
- Do not hide database-specific behavior behind fake portability.

That command is not magic. It is just a tidy boundary around the work.

Database portability is where the hard parts live

SQLAlchemy, the Python SQL toolkit and ORM, is a sensible foundation for this kind of experiment because it already knows how to talk to many engines. But a shared API does not erase database differences.

The hard parts are usually the boring ones: conflict handling, type reflection, default values, transaction behavior, identifier quoting, JSON support, and what “upsert” means across engines. PostgreSQL, SQLite, and DuckDB overlap a lot, but they are not the same database wearing different hats.

That is why the test matrix matters. If a coding agent writes a beautiful abstraction that only runs on SQLite, it has not built a database-agnostic library. It has built a SQLite library with optimistic naming.

The trap is accepting a green unit test suite that mocks away the database. For a tool like this, at least one test should touch each promised engine, even if the first alpha only supports a narrow slice.

Borrow the spike shape, not the hype

The practical takeaway is simple: use alchemy-utils 0.1a0 as a pattern for bounded AI coding experiments. Pick one real library-shaped problem, name the methods, name the test matrix, and require a runnable command before you call it done.

This fits neatly beside the related training topic, but it should not be turned into a ceremony. The lesson is smaller and better: a coding agent can move quickly when the task has a reference implementation, a test harness, and a visible release threshold.

The trap is asking for production confidence from an alpha spike. An alpha can prove direction, API taste, and test feasibility. It cannot prove long-term maintenance, edge-case correctness, or compatibility with every database dialect your users will bring.

If you want a nearby comparison in a different technical domain, Discovered Materials Uses Agents for Chip Heat is another example of agents being useful when the work is boxed into a measurable experiment.

Copy this small spike receipt

Use this when you want a coding agent to build a prototype that can be reviewed without replaying the whole chat.

AI coding spike receipt

Project:
- Name:
- One-sentence goal:
- Existing project or API to imitate:

Boundaries:
- Must include:
- Must not include:
- Known unsupported cases:

Execution:
- Package/init command:
- Test command:
- Minimum runnable CLI or script:
- Commit rule:

Compatibility:
- Runtime versions:
- External services required:
- Database, browser, or API targets:

Review evidence:
- Passing tests:
- Example command output:
- Files changed:
- Follow-up risks:

For a Claude Code repo, keep this as a slash-command template rather than permanent repository memory. If the rule is specific to one spike, it belongs in the command or task prompt; if it is a durable repo constraint, then a short note in CLAUDE.md can make sense.

Watch the next alpha

Try the package only on a disposable database or local copy, then read the tests before trusting the abstraction. The next useful signal will be how many database-specific edge cases become explicit instead of hidden.

One methodology lens

One useful way to read this through our methodology is the Plan step: delegate first-pass decomposition and dependency mapping, review the sequencing and assumptions, and keep ownership of scope and priorities. If that split is still fuzzy, the workflow usually is too.

Practical starter checklist

- [ ] Name the Claude Code artifact first: a hook boundary, an MCP permission note, a slash-command workflow, a Claude skill outline, a review checklist, or a concise CLAUDE.md note when repository memory is the topic.
- [ ] Write the review checklist before generation starts: scope, owner, tests, rollback.
- [ ] Keep the first step small enough that a reviewer can inspect the receipt without replaying the whole chat.

Common questions

  • How should teams start with Claude Code?

    Start by writing down one visible team rule for Claude Code, not a loose preference. That usually means a short repository convention, a review checklist, and one owner who can reject agent output when the evidence is missing.

  • Which Claude Code artifact should teams standardize first?

    Standardize the smallest artifact that reviewers already touch: a hook checklist, MCP permission rule, slash-command workflow, skill outline, or concise CLAUDE.md note. The point is not documentation volume; it is a shared place where scope, allowed tools, expected tests, and rollback notes are visible before generated code reaches review.

  • How do teams know the convention is working?

    The convention is working when reviewers can approve or reject agent output from the artifact and evidence alone. Track whether pull requests name the rule used, include the promised checks, and avoid replaying long sessions just to understand what changed.

Best ways to use this research

  • Best for: Claude Code teams deciding which hook, skill, MCP boundary, slash-command workflow, review habit, or repository-memory convention to standardize next around “Simon Willison Ships alchemy-utils Alpha.”
  • Best first artifact: turn the named fix into a hook checklist, skill note, MCP permission note, review receipt, or concise CLAUDE.md convention when repository memory is the real topic before the next automated run.
  • Best comparison angle: compare the workflow against the current Claude Code handoff, hook behavior, and MCP scope; keep the path that leaves the shortest auditable trail.

Further reading

Where to go next

Start from the related training topic and make the first exercise prove scope, verification, and ownership in the PR body.

Related training topics

Related research

Continue through the research archive

Ready to start?

Transform how your team builds software.

Book a 15-minute sync