Instructions for AI coding agents working with this codebase.
Always check the latest version before installing a package.
Before adding or updating any dependency, verify the current latest version on npm:
npm view <package-name> versionOr check multiple packages at once:
npm view ai version
npm view @ai-sdk/provider-utils version
npm view zod versionThis ensures we don't install outdated versions that may have incompatible types or missing features.
- Do not use emojis in code or UI
- Use shadcn CLI to add shadcn/ui components:
pnpm dlx shadcn@latest add <component> - Web app docs (
apps/web/): Never use Markdown table syntax (| col | col |). Always use HTML<table>with<thead>,<tbody>,<tr>,<th>,<td>. Markdown tables do not render correctly in the web app. Inside HTML table cells, curly braces must be escaped as JSX expressions (e.g.<code>{'{ "$state": "/path" }'}</code>) because MDX parses{as a JSX expression boundary.
When using the Vercel AI SDK (ai package) with AI Gateway, pass the model as a plain string identifier -- do not import a provider constructor:
import { streamText } from "ai";
const result = streamText({
model: "anthropic/claude-haiku-4.5",
prompt: "...",
});This requires AI_GATEWAY_API_KEY to be set in the environment. See tests/e2e/ for examples.
All apps and examples with dev servers use portless to avoid hardcoded ports. Portless assigns random ports and exposes each app via .localhost URLs.
Naming convention:
- Main web app:
json-render→json-render.localhost:1355 - Examples:
[name]-demo.json-render→[name]-demo.json-render.localhost:1355
When adding a new example that runs a dev server, wrap its dev script with portless <name>:
{
"scripts": {
"dev": "portless my-example-demo.json-render next dev --turbopack"
}
}Do not add --port flags -- portless handles port assignment automatically. Do not add portless as a project dependency; it must be installed globally.
- Run
pnpm type-checkafter each turn to ensure type safety - When making user-facing changes (new packages, API changes, new features, renamed exports, changed behavior), update the relevant documentation:
- Package
README.mdfiles inpackages/*/README.md - Root
README.md(if packages table, install commands, or examples are affected) - Web app docs in
apps/web/(if guides, API references, or examples need updating) - Skills in
skills/*/SKILL.md(if the package has a corresponding skill) AGENTS.md(if workflow or conventions change)
- Package
Releases are manual, single-PR affairs. The maintainer controls the changelog voice and format.
All public @json-render/* packages share the same version. The canonical version lives in packages/core/package.json.
When asked to prepare a release (e.g. "prepare v0.17.0"):
- Create a branch (e.g.
prepare-v0.17.0) - Bump the version in
packages/core/package.json - Run
pnpm run version:syncto update all other@json-render/*packages - Write the changelog entry in
CHANGELOG.md, wrapped in<!-- release:start -->and<!-- release:end -->markers (move the markers from the previous entry to the new one) - Fill documentation gaps — every public package should have:
- A row in the root
README.mdpackages table - A renderer section in the root
README.md(if it's a renderer) - An API reference page at
apps/web/app/(main)/docs/api/<name>/page.mdx - An entry in
apps/web/lib/page-titles.tsandapps/web/lib/docs-navigation.ts - An entry in the docs-chat system prompt (
apps/web/app/api/docs-chat/route.ts) - A skill at
skills/<name>/SKILL.md - A
packages/<name>/README.md
- A row in the root
- Run
pnpm type-checkafter all changes to verify nothing is broken - Open a PR and merge to
main
CI compares the @json-render/core version to what's on npm. If it differs, it builds, publishes all public packages, and creates the GitHub release automatically. The release body is extracted from the content between the markers.
pnpm run version:sync— sync all@json-render/*package versions to match@json-render/corepnpm run version:check— verify all versions are in sync (runs in CI)pnpm run ci:publish— build all packages and publish to npm (CI only)
Source code for dependencies is available in opensrc/ for deeper understanding of implementation details.
See opensrc/sources.json for the list of available packages and their versions.
Use this source code when you need to understand how a package works internally, not just its types/interface.
To fetch source code for a package or repository you need to understand, run:
npx opensrc <package> # npm package (e.g., npx opensrc zod)
npx opensrc pypi:<package> # Python package (e.g., npx opensrc pypi:requests)
npx opensrc crates:<package> # Rust crate (e.g., npx opensrc crates:serde)
npx opensrc <owner>/<repo> # GitHub repo (e.g., npx opensrc vercel/ai)