Get started
Getting started with Coho
Sign up free, pick the CLI or the portal, create a project, define types, write content, and generate a typed library for .NET, Java, Kotlin, Node or Python.
Welcome. Coho is managed content infrastructure: your content and the types that describe it are versioned together, and they branch, diff, merge and ship the way the rest of your stack does.
There are native clients for .NET, Java, Kotlin, Node and TypeScript, and Python, with more in development. Each one is generated from your own content model rather than written against a generic entry, so the code that reads a field knows the field exists, and a field you retire breaks a build instead of a page.
This page is the short version: the steps in the order you take them, what each one is for, and the tutorial that walks it through. None of it needs a card.
Sign up
The free plan is the place to start, and it is enough to put a personal project live and learn
how the whole platform works: one project, 10 MB of content — about 2,000 entries — three
editors, dev and prod, 5,000 live reads a day and 2 GB of delivery a month.
Branches, tags, diffs, merge previews, merges, promotions and rollbacks are never charged, on any plan. The tools of good practice are not a tier.
Create an account — or, if you would rather not leave
the terminal, coho signup "Your organization" opens the same page.
Pick a door: the CLI or the browser
Two doors into the same project, and the same contract behind both.
The portal edits content, shows diffs and promotes releases in the
browser. The coho CLI does the same from a shell, a
script or CI, with --output json whenever something other than a person is reading.
Most of the tutorials use the CLI, on purpose. A command names the thing it acts on and the ref it acts on, so the fundamentals — refs, versions, diffs, merges, releases — stay on the screen instead of behind a button. Translating to the portal afterwards is easy, because every screen in it is one of the commands you have already run.
Install the CLI, then sign in:
coho login
coho whoami
Create a project
A project holds one content model, its content, and the refs that content travels along.
coho project create "Acme"
That creates the project with its trunk, v0.0.x, and its environments, and points your
commands at it. coho status answers "where am I?" at any moment: the credential in use, the
account, the project, the ref, and your role there.
Define your types
A type is a JSON definition — its fields, their kinds, which are required, which are localized. Keep them in your repository and review them like any other change.
coho type put -f types/article.json
Types are versioned on the ref, alongside the content. A type change and the content that needs it land in the same release, so there is never a window where the schema and the entries disagree.
Create content
coho entry create --type article -f posts/hello.json
coho entry list --type article
Do it on a branch rather than on the trunk, and the work is reviewable before it is anybody else's problem:
coho branch create copy/launch
# write, then look at what you did
coho diff v0.0.x copy/launch
coho merge copy/launch --into v0.0.x --reviewed
Then cut a release from the trunk and move an environment at it:
coho tag create v0.1.0 --branch v0.0.x --validate
coho promote dev v0.1.0
A tag is immutable, so dev and prod can point at different ones, and a rollback is the
environment moving back rather than content being rewritten.
Bootstrap your code
Whatever the framework or the language, the pattern is the same: generate a library from your content model, then read content through it.
Make it a package of its own rather than a folder inside one application. A single library can then be shared by several applications, or by several layers of one — a web front end, a service behind it, a batch job beside it — and every one of them reads the same types.
| Language | Start with | Template |
|---|---|---|
| Node and TypeScript | npm create coho | coho-template-typescript |
| .NET | dotnet new coho-library | coho-template-dotnet |
| Python | coho-codegen create | coho-template-python |
| Java | coho-delivery-sdk-jvm | coho-template-java |
| Kotlin | coho-delivery-sdk-jvm | coho-template-kotlin |
The library is strongly typed to your own model: an Article with the fields you gave it, not a
dictionary you index and hope. Regenerate it when the model changes and the compiler tells you
which call sites moved. This is the best way to read content, and it is the way every tutorial
here does it.
The same code reads any ref. A project token reads dev or a branch while you work; a delivery
key reads released content in production. Which one is in the environment decides what the build
sees, and neither ever reaches the browser.
Or read it as plain JSON
A library is the best way, not the only one. Delivery also answers as a REST endpoint and a GraphQL endpoint, both with the same content and the same keys, which is what you want for a language with no native client yet, a one-off script, or something that is not a build at all.
The tutorials
Each sample in coho-samples is self-contained: its own folder, its own README, and steps numbered in the order you take them. All of them build the same blog content model, so you can read one in a language you know and then follow another.
| Tutorial | What it builds |
|---|---|
| Next.js blog | A TypeScript library and a Next.js site — start here |
| ASP.NET Core blog | A C# library and a Razor Pages site |
| FastAPI blog service | A library of Pydantic models and a JSON service |
| Spring Boot blog service | A Java library and a Spring Boot service |
| Ktor blog service | A Kotlin library and a Ktor service |
| OpenAlex research catalog | Tens of thousands of real entries, a type tree four levels deep |
For the ideas underneath the commands, the knowledge base is the place: branches, tags and environments explains the refs, why a schema change should ship with its content explains why the two move together, bulk-loading your content covers getting real volume in, and rebuilding a static site when content is released covers the last step, where a release reaches readers.
One shared line, then a lane for each job.
Log in once and pick an account. Then model and write content in the authoring lane, and release it in the lane below. Every command below is the verbatim quickstart.
Install the CLI with the instructions in the coho-cli repository.
acme is the labelled sample account used across this site.
The shared line
- 01
coho loginPKCE in the browser. The token goes to the OS keyring. - 02
coho use acmeSets the sticky context. acme is a sample account.
I model and write content
- 03
coho project create "Marketing site" - 04
coho type put blogPost --file blogPost.json
- 05
coho entry create -t blogPost -s hello-world --set title.en-US="Hello, world" --set rank=1 - 06
coho branch create feature/pricing --use
I ship releases
- 07
coho diff v0.0.x - 08
coho merge --into v0.0.x -m "New pricing copy" --reviewed - 09
coho tag create v1.0.0 -m "First release" - 10
coho promote qa v1.0.0 - 11
coho promote prod v1.0.0 -m "Go live" - 12
coho rollback prod
I build the frontend
- 13
coho key create --label site-prod --ref prodThe key is shown once. Send it as a Bearer header. - 14
coho invite create jane@acme.example --role memberInvite a teammate to the sample account.
On a small team one person holds every role. Run the authoring lane, then the release lane.