Source: https://www.hype-stack.dev/stacks/ai-agent-boilerplate

# AI Agent Boilerplate: Auth, Billing, and Streaming Chat

> A good AI template does not give an agent more code to guess through. It gives the agent a codebase it can read,
> change, and prove correct.

An ordinary starter is easy to judge at first: install it, run it, and see how much setup disappeared. An **AI agent
boilerplate** needs another test once coding agents begin making real changes.

Can the agent discover how this repository works without inventing an architecture? Can it change one feature without
opening unrelated parts of the application? Can it run the relevant checks while the edit is still in context?

That is where Hype Stack fits. It is a full-stack codebase with project rules, installed skills, vertical feature
folders, and compiled lint and typecheck tools. The sections below examine each part before looking at a specific
template built on top of them.

**See AI agent templates** Browse complete application starters built on Hype Stack, with the repository rules, feature structure, and verification tools discussed below.

[Browse the templates](https://www.hype-stack.dev/templates)

## Three tests for a good AI template

The useful definition is smaller than most feature lists. A template built for coding agents needs three things:

- **Rules and skills with opinions** The repository tells an agent how this application handles errors, data access, routes, and feature work. Repeatable procedures are installed as versioned skills rather than copied from the latest prompt thread.
- **A vertical codebase** Code that changes together lives together. One task fits inside a feature boundary, so the agent can understand the job without loading unrelated layers into context.
- **A fast, unforgiving feedback loop** Linting, formatting, and typechecking use compiled tools. Repository-specific lint rules report some architecture violations alongside ordinary code mistakes.

_Together, these reduce three kinds of guesswork: project conventions, where a change belongs, and whether the change worked._

The three reinforce each other. Rules define the path. Vertical features keep that path short. Fast checks tell the
agent when it stepped off.

## Rules should describe this codebase, not software in general

Telling an agent to "write clean code" costs tokens and changes nothing. It already saw that sentence in its training
data. A useful rule records a decision it could not infer safely.

Hype Stack ships those decisions in `.cursor/rules`. Backend errors bubble to one middleware. Page routes return a
breadcrumb from their loaders. Frontend requests go through the typed SDK rather than raw `fetch`. The repository also
intends feature modules to call functions in `db/queries` and `db/mutations` instead of importing the database client.

The strongest rules do not stop at prose:

1. **Errors belong to the central middleware** — An agent is told to throw typed errors instead of returning one-off JSON error responses from a route.
2. **Lint rejects the wrong shape** — rules/no-json-error-response.ts reports a route that returns c.json(body, 404), during the same check the agent already runs.
3. **The failure points to the accepted path** — The agent gets a local, mechanical correction instead of waiting for a reviewer to explain the architecture after the pull request is finished.

Skills handle a different job. A rule says what must remain true. A skill is a procedure for doing a particular kind of
work, such as reviewing a pSEO page or creating an installable pack. Procedures can change upstream, so Hype Stack pins
installed skills by repository and content hash in `skills-lock.json`. An update arrives as a diff you review, not as a
new set of instructions silently entering the next agent session.

> If a project decision matters on the hundredth agent edit, it cannot live only in the memory of whoever reviewed the
>   first one.

Premade rules and skills are not magic context. Some will be wrong for your product. Their value is that the template
starts with one coherent opinion, every exception is visible, and the mechanical parts can be checked.

The checks are not complete. The database restriction currently rejects imports from `@backend/db/postgres`, but a
module can still reach the same client through `@backend/context`. Several organization invitation modules do exactly
that. The rule records the intended boundary, but the lint pattern needs widening before it enforces that boundary.

## A vertical codebase fits the task into context

The phrase "vertical codebase" comes from
[TkDodo's article of the same name](https://tkdodo.eu/blog/the-vertical-codebase). The core idea is direct: organize by
what the application does, not only by what kind of file something is.

That distinction matters more when an agent is reading the repository. Imagine asking it to change how organization
invitations are resent. In a layer-first codebase, the relevant route, service, email, schema, test, and shared types
may sit in distant trees. The agent searches broadly, loads near matches, and has to infer which abstraction is current.

In Hype Stack, the operation has a neighborhood:

**your-app**

- apps/backend/prisma/schema/
  - organization.prisma — Models, relations, cascades
  - invitation.prisma — The schema for this feature
- apps/backend/src/features/organizations/
  - modules/resend-organization-invitation/
    - index.ts — One operation, one folder
    - index.test.ts — Its integration test, beside it
- apps/frontend/src/features/organization/
  - switch-organization/switch-organization.tsx — A neighboring organization operation

This does not mean every file sits in one folder. Prisma schemas stay split by feature so the agent can see relations
and cascade behavior without a live production database. Shared database helpers and routes still have their own
locations. Vertical architecture is not "put everything together." It is "make the path through one feature obvious."

That path is also easier for a human to review. A new operation arriving as one folder has a visible edge. The same
change scattered across generic service files looks like six unrelated edits until the reviewer reconstructs the task.

## The Vite/Oxc toolchain changes the feedback loop

An agent works in a loop: read, edit, check, repair. The duration of the check affects how often the last two steps
happen.

Hype Stack uses Vite 8 with Rolldown and Oxc underneath, oxlint and oxfmt for linting and formatting, and the Go-native
TypeScript compiler (`tsgo`) for typechecking. We ran both toolchains across the same repository:

**One full check: lint, then typecheck**

- **ESLint and tsc:** 2m 24s (107s of type-aware ESLint on the typescript-eslint recommended rules, then 37s of tsc 6.0.3)
- **oxlint and tsgo:** 10s (1.5s of oxlint across 227 rules, then 9s of the Go compiler)

_A local snapshot across 793 TypeScript files in the two apps in this repository, measured on an Apple Silicon laptop. Both rows checked the same files. Treat this as a repository measurement, not a general benchmark of every ESLint or Oxc setup._

The difference changes working behavior. A check that finishes while the edit is still fresh is practical to run after
small changes. A longer check is more likely to run after a batch, which means the agent receives feedback several edits
after the mistake that caused it.

Fast tools alone do not make an AI template good. A fast lint run that only catches syntax is still weak. Here oxlint
runs the ordinary lint rules and custom checks such as `rules/no-json-error-response`; `tsgo` runs afterward as a
separate typecheck. Re-run both on your own machine and project before using these numbers for a tooling decision.

## What "production-ready" has to mean for an agent

Most repositories that call themselves a production-ready AI agent template are a chat loop, a vector store, and a
Dockerfile. The loop is the easy part. What breaks first once real users arrive is everything around it: who is allowed
to spend tokens, what happens when a stream dies halfway, and whether a tool call can be trusted.

**What the AI Chat pack handles**

- **Spend is admitted before the request leaves** The AI Chat pack counts the serialized request with the provider's own token counter, reserves input plus the output cap against the workspace allowance, and only then calls the model. A plan limit is enforced on the server, not by hiding a button.
- **A dead stream does not leak a reservation** A recovery job (ai-chat-recovery) finds runs that never finished, reconciles their usage holds in order, and purges deleted conversations, so a crashed worker cannot leave a workspace charged for tokens it never received.
- **Tools are typed contracts, not prompt text** Each tool is declared with defineToolContract: strict input and output schemas, an executor that checks authorization and availability itself, and a renderer. A missing executor or renderer is a type error.
- **Grounding runs off the request path** Uploaded PDFs, Word and Excel files are parsed, embedded and indexed on a Postgres-backed queue, so a large upload does not block a chat turn, and a sweep job retries what failed.

What it does not have is as useful to know. There is no tracing or evaluation suite, so add Langfuse or Logfire (their
products, with their own bills) when you need to see why an answer went wrong. There is no multi-agent graph; if your
product is an orchestration of agents, LangGraph or a durable workflow engine sits beside this, not inside it. And it is
TypeScript end to end. If your agent logic already lives in Python with Pydantic AI, a Python template will fit you
better than porting it.

## What Aether adds on top of a chat kit

Aether is the concrete example: an AI product shell with React and Hono, auth, organizations, Stripe billing, an admin
app, and the AI Chat pack's workspace at `/chat` and `/knowledge`.



The chat runs on the Vercel AI SDK with OpenAI, Anthropic and Google adapters, each switched on by its own API key and
left out of the model picker without one. Images, speech, transcription and embeddings use OpenAI only, so a Claude chat
borrows OpenAI's image model. The three tools that ship are web search, image generation and search over the workspace's
own documents.

If all you need is a chat component, a free kit such as Vercel's AI Elements will do and you can stop there. The
template is for the larger job:

|  | Aether on Hype Stack | A chat component kit |
| --- | --- | --- |
| Chat interface | Streaming chat on web and the Expo app | The source components |
| Accounts and organizations | Outside the kit | Working code on your Postgres |
| Token allowances | Outside the kit | Per-workspace caps tied to Stripe plans |
| Agent instructions | Defined by your host project | Project rules and pinned skills |
| Repository structure | Defined by your host project | Vertical feature folders; selected boundaries enforced in lint |
| Your domain tools | You write them | You write them |

That last row is the boundary that matters. The template cannot know whether your product reviews contracts, runs
support workflows, or operates a browser. Those tools are your product. What it gives you is the place they plug in: a
contract in the shared feature, an executor on the backend, a renderer on the frontend, and nothing in the stream loop
to edit. Billing per token or per credit is not there either; the billing pack does subscription tiers.

## The verdict

Judge an AI agent boilerplate with a test more demanding than `pnpm dev`.

Give a coding agent one realistic change. Watch how much of the repository it has to read. Check whether project rules
name decisions that matter, whether those decisions fail mechanically, and whether the complete check is fast enough to
run before the agent loses the thread.

Aether gives that test a credible starting point:

- Premade, opinionated rules and versioned skills tell the agent how this repository works.
- Vertical feature folders keep related operations and tests near each other.
- oxlint, oxfmt, tsgo, and custom lint checks provide the verification tools.
- A working, metered chat agent with three tools, so the first change you ask for is a new tool, not the plumbing.

It is not finished. The database import restriction has a hole, the actual check duration needs measuring after
installation, and there is no tracing or evaluation built in. It also does not know what your agent is for. It gives you
a running agent with the cost and recovery paths already handled, and a repository with explicit guidance for the coding
agent that will write the rest. Whether that is the right division depends on how much of the customer-facing agent you
already know how to build.



The backend underneath is described in
[Hono Prisma Starter with Postgres, Typed Client and Docker](/stacks/hono-prisma-starter), the hosting question in
[Self-Hosted AI Agents](/stacks/self-hosted-ai-agents), and the no-code route in
[No Coding AI Agent](/stacks/no-coding-ai-agent).
