Build a feature with Claude Code
In Tutorial 3 you built a feature by hand. Here you’ll build the same kind of feature, a list of bookmarks owned by the user, by describing it. The Claude Code plugin does the scaffolding, writes the code and tests, wires it into the SPL and product, migrates, and verifies.
Table of contents
Prerequisites
- The Claude Code plugin installed. See Claude Code → Installation.
- A product to build into (e.g.
my_first_appfrom Tutorial 1) with the SPLENT CLI container running. - A feature name that is still free.
my_first_appalready hassplent_feature_notesfrom Tutorial 3, which is why this tutorial builds bookmarks instead of notes.
Step 1. Describe what you want
You don’t type CLI commands. In Claude Code, just say what the feature is.
add a bookmarks feature with a title and a URL, owned by the user
Claude recognises this as SPLENT feature work and runs the feature skill. It
infers a name (splent_feature_bookmarks), an archetype (full, because it has a
model), and that “owned by the user” means a foreign key to the auth user
table, so it depends on auth. It states that plan in a couple of lines before
it starts.
Step 2. What Claude does
The skill drives the CLI end-to-end, writing real code at each step.
# scaffold the package (feature creation is workspace-level)
splent product:deselect
splent feature:create splent-io/splent_feature_bookmarks --type full
# write idiomatic code (Claude does this, following the conventions):
# models.py Bookmarks(id, title, url, user_id → user.id, created_at)
# repositories.py custom queries on BaseRepository
# services.py business logic on BaseService
# routes.py @login_required /bookmarks/ (resolved via service_proxy)
# forms.py, templates/bookmarks/index.html, hooks.py (sidebar), seeders.py
# tests/unit, tests/integration, tests/functional
# add to the SPL (spl:* runs detached; dependencies are auto-detected)
splent spl:add-feature sample_splent_spl splent_feature_bookmarks # → bookmarks => auth
# install into the product
splent product:select my_first_app
splent feature:add splent-io/splent_feature_bookmarks
# infer and write the contract (needs a selected product)
splent feature:contract splent_feature_bookmarks --write
# migrate
splent db:migrate splent_feature_bookmarks
splent db:upgrade
These are the same commands you typed in Tutorial 3, in the same order.
Claude follows two rules throughout. The CLI owns the mechanics (it never hand-edits pyproject feature lists, the
.uvlmodel, or migration tables), and you own the logic (models, services, routes, templates, tests).
Step 3. Verify
splent feature:test splent_feature_bookmarks # unit, integration, functional
splent feature:xray --validate # hooks/extension wiring OK
splent product:validate # UVL satisfiable, contracts compatible, imports OK
splent product:routes | grep bookmarks
product:routes prints one line per route and method, in the same shape as
the notes routes you built by hand.
/notes/ GET splent_feature_notes notes.index
/notes/<int:note_id>/delete POST splent_feature_notes notes.delete
/notes/<subfolder>/<filename> GET splent_feature_notes notes.assets
/notes/create GET splent_feature_notes notes.create
/notes/create POST splent_feature_notes notes.create
The assets route is not one you wrote: a feature with an assets/ folder,
which the scaffold creates, serves its JavaScript and CSS from it under its prefix.
Open http://localhost:5591/login, log in, and go
to the new page (/bookmarks/, or whatever route Claude reported). Its sidebar
has a Bookmarks link next to Notes, and the page lists the current
user’s bookmarks and lets them add and delete their own. Claude writes the code
afresh each time, so names and details can differ from this description; the
summary it prints at the end says what it built.
When the app won’t boot
If product:derive fails with ValueError: Unrecognized value for
SESSION_TYPE: null, the product has no session backend selected. Ask Claude for help.
/splent:doctor the app won't start, SESSION_TYPE is null
The doctor skill diagnoses it and adds a session feature
(splent_feature_session_filesystem or _redis) to the SPL and product, then
re-derives.
What you end up with
A complete, tested feature, splent_feature_bookmarks, added to the SPL with a
bookmarks => auth constraint, installed and migrated into your product, and
serving a login-protected page. The same kind of result as
Tutorial 3, reached by describing the feature instead of
writing every file.
Tips
- Prefer describing intent; the right skill (
feature,product,doctor) triggers automatically. See the Skills reference. - Review the diff like any change. Claude writes idiomatic SPLENT code, but it’s your feature.