ワンクリックで
kagaribi-development
Create packages, generate models, and develop Kagaribi applications locally
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Create packages, generate models, and develop Kagaribi applications locally
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | kagaribi-development |
| description | Create packages, generate models, and develop Kagaribi applications locally |
Guide Claude through package creation, model generation, local development, and inter-package communication.
Kagaribi is designed as a framework for the AI coding agent era.
Context Minimization
Separation of Concerns
Type Safety
getClient<T>()Each package is independent in these aspects:
ABSOLUTE RULE: .ts files MUST NOT contain HTML template literals. ALWAYS use .tsx files with React/JSX components for views.
❌ ABSOLUTELY FORBIDDEN:
// ❌ NEVER DO THIS - HTML template literals in .ts files
import { html } from 'hono/html';
app.get('/', (c) => {
return c.html(html`<html><body>...</body></html>`);
});
// ❌ ALSO FORBIDDEN - Any HTML strings in .ts files
app.get('/page', (c) => {
return c.html(`
<html>
<body><h1>Title</h1></body>
</html>
`);
});
✅ CORRECT APPROACHES:
For APIs - Return JSON in .ts files:
// ✅ .ts files for JSON APIs
app.get('/api/users', (c) => {
return c.json({ users: [] });
});
For Views - Use .tsx files with React/JSX:
// ✅ Create views/HomePage.tsx
import { FC } from 'hono/jsx';
export const HomePage: FC = () => {
return (
<html>
<body>
<h1>Welcome</h1>
</body>
</html>
);
};
// ✅ Use .tsx for routes that render views
// src/index.tsx (note: .tsx extension)
import { Hono } from 'hono';
import { HomePage } from '../views/HomePage';
const app = new Hono()
.get('/', (c) => c.html(<HomePage />));
export default app;
Why This Rule Exists:
See: Views Guide for detailed documentation.
npx kagaribi new <name> [--node|--cloudflare|--lambda|--cloudrun|--deno]
Examples:
# Co-located package (runs with root by default)
npx kagaribi new users
# Package targeting Cloudflare Workers
npx kagaribi new payments --cloudflare
# Package targeting AWS Lambda
npx kagaribi new analytics --lambda
What gets created:
packages/<name>/kagaribi.package.ts - Package manifestpackages/<name>/src/index.ts - Hono app templatekagaribi.config.ts with new package entrynpx kagaribi dev [port]
Examples:
npx kagaribi dev # http://localhost:3000 (default)
npx kagaribi dev 8080 # http://localhost:8080
All packages run in a single process with automatic routing.
npx kagaribi model new <table> <field:type>... [--db postgresql|mysql|sqlite] [--scope <packagePath>]
Supported field types: string, integer, boolean, timestamp, text
Examples:
# Generate posts table with title and content
npx kagaribi model new posts title:string content:text --db postgresql
# Generate products table
npx kagaribi model new products name:string price:integer stock:integer
# Auto-detect database dialect from config
npx kagaribi model new comments postId:integer userId:integer body:text
# Generate model in specific package's db directory (scoped database)
npx kagaribi model new users name:string email:string --scope packages/auth
What gets created (root db directory):
db/schema.tsdb/models/<table>.ts with helper functionsdb/models/index.ts to export the modelWith --scope flag (per-package db directory):
<scope>/db/schema.ts<scope>/db/models/<table>.ts with helper functions<scope>/db/models/index.ts to export the modelAfter generation:
npx drizzle-kit generate # Create migration files
npx drizzle-kit push # Apply to database
Database Access Patterns:
Kagaribi supports two ways to access database:
Shared Database with Model Helpers (default when using kagaribi model new)
findAll(), findById(), create(), remove()import * as Posts from '../../../db/models/posts.js'Per-Package Database Access (direct Drizzle ORM)
getDb() and schema directly in package codeconst db = getDb(); await db.select().from(schema.users)See Database Integration Guide for detailed comparison and best practices.
Each package is a self-contained Hono application:
app instancepackages/
users/
kagaribi.package.ts # Manifest (dependencies, routes, runtime)
src/
index.ts # Hono app with routes
Example decision:
auth) - independent concernusers package - tightly coupled to user datapayments) - separate domainpayments or be separate based on deployment needsEdit packages/<name>/kagaribi.package.ts to define dependencies and routes:
import { definePackage } from '@kagaribi/core';
export default definePackage({
name: 'articles',
dependencies: ['users', 'auth'], // Required packages
routes: [
'/users/:userId/articles', // Nested routing pattern
],
runtime: ['node', 'cloudflare-workers', 'deno'],
});
Key fields:
name - Package identifier (must match directory name)dependencies - Other Kagaribi packages this package calls via RPCroutes - Custom nested route patterns (optional)runtime - Compatible deployment targetsimport { Hono } from 'hono';
const app = new Hono()
.get('/api/items', async (c) => {
return c.json({ items: [] });
})
.get('/api/items/:id', async (c) => {
const id = c.req.param('id');
return c.json({ id, name: 'Item' });
})
.post('/api/items', async (c) => {
const body = await c.req.json();
// Create item logic
return c.json({ id: 1, ...body }, 201);
});
// IMPORTANT: Export type for RPC clients
export type ItemsApp = typeof app;
export default app;
import { Hono } from 'hono';
import { createDb, createDbMiddleware } from '@kagaribi/core';
import * as schema from '../../../db/schema.js';
const { initDb, getDb } = createDb('postgresql', schema);
const app = new Hono()
// Initialize database connection
.use('*', createDbMiddleware({ initFn: initDb }))
.get('/api/users', async (c) => {
const db = getDb();
const users = await db.select().from(schema.users);
return c.json(users);
})
.post('/api/users', async (c) => {
const db = getDb();
const { name, email } = await c.req.json();
const [user] = await db.insert(schema.users)
.values({ name, email })
.returning();
return c.json(user, 201);
});
export type UsersApp = typeof app;
export default app;
createDbMiddleware() features:
process.env.DATABASE_URL) or Cloudflare Workers (c.env.DATABASE_URL)initDb() with connection stringD1 uses a binding object instead of a URL connection string, so set isBinding: true.
import { Hono } from 'hono';
import { createDb, createDbMiddleware } from '@kagaribi/core';
import * as schema from '../../../db/schema.js';
// Bindings type definition
type Env = { Bindings: { DB: D1Database } };
const { initDb, getDb } = createDb('sqlite', schema, { driver: 'd1' });
const app = new Hono<Env>()
.use('*', createDbMiddleware<D1Database>({
initFn: initDb,
envVarName: 'DB', // Binding name from wrangler.toml
isBinding: true, // Pass binding object directly to initFn (for D1)
}))
.get('/api/users', async (c) => {
const db = getDb();
const users = await db.select().from(schema.users);
return c.json(users);
});
export type UsersApp = typeof app;
export default app;
createDbMiddleware options:
initFn - Database initialization functionenvVarName - Environment variable or binding name (default: 'DATABASE_URL')isBinding - When true, passes binding object directly to initFn (for D1)Absolute Rule: Direct inter-package communication is prohibited. Always go through the root package.
Centralized Authentication & Authorization
Centralized Orchestration
Clear Dependency Management
kagaribi.package.ts dependenciesClient Request → Root Package → Package A
↓
→ Package B
↓
← Response
Warning: Direct calls from Package A to Package B is a design mistake. Root package should aggregate necessary data before passing to each package.
Each package exports type definitions to be referenced by other packages.
Improved AI Agent Accuracy
Implementation Separation
// packages/users/src/index.ts
import { Hono } from 'hono';
const app = new Hono()
.get('/api/users/:id', async (c) => {
// implementation...
});
// ✅ REQUIRED: Export type definition
export type UsersApp = typeof app;
export default app;
Without export type UsersApp = typeof app, other packages cannot call it type-safely.
Views must be written in TSX. Direct HTML string literals in code are prohibited.
Type Safety
html tag literals don't have type checkingReusability
Maintainability
import { html } from 'hono/html';
app.get('/', (c) => {
return c.html(html`
<html>
<body>
<h1>Hello</h1>
</body>
</html>
`);
});
import { jsx } from 'hono/jsx';
const Layout = ({ children }: { children: any }) => (
<html>
<body>{children}</body>
</html>
);
const HomePage = () => (
<Layout>
<h1>Hello</h1>
</Layout>
);
app.get('/', (c) => {
return c.html(<HomePage />);
});
Use getClient<T>() for type-safe calls between packages:
Important: This feature is primarily used for calling packages from the root package. Do not use for direct inter-package communication (see "Inter-Package Communication Rules" above).
import { Hono } from 'hono';
import { getClient } from '@kagaribi/core';
import type { UsersApp } from '../../users/src/index.js';
import type { AuthApp } from '../../auth/src/index.js';
const users = getClient<UsersApp>('users');
const auth = getClient<AuthApp>('auth');
const app = new Hono()
.get('/api/profile', async (c) => {
// Call users package
const res = await users.api.users[':id'].$get({
param: { id: '123' },
});
const user = await res.json();
return c.json(user);
})
.post('/api/verify', async (c) => {
// Call auth package
const token = c.req.header('Authorization');
const res = await auth.api.verify.$post({
json: { token },
});
const result = await res.json();
return c.json(result);
});
export type ProfileApp = typeof app;
export default app;
Key points:
// packages/articles/kagaribi.package.ts
export default definePackage({
name: 'articles',
dependencies: ['users'],
routes: ['/users/:userId/articles'], // Handle user-specific articles
});
import { Hono } from 'hono';
import { kagaribiParamsMiddleware } from '@kagaribi/core';
const app = new Hono();
// Apply middleware to extract params from X-Kagaribi-Params header
app.use('*', kagaribiParamsMiddleware());
app.get('/', (c) => {
// Access extracted parameters
const userId = c.get('userId' as never) as string;
return c.json({ userId, articles: [] });
});
app.get('/:articleId', (c) => {
const userId = c.get('userId' as never) as string;
const articleId = c.req.param('articleId');
return c.json({ userId, articleId, title: 'Article Title' });
});
export type ArticlesApp = typeof app;
export default app;
npx kagaribi new orders --node
Edit packages/orders/kagaribi.package.ts:
export default definePackage({
name: 'orders',
dependencies: ['users', 'payments'],
runtime: ['node', 'cloudflare-workers'],
});
npx kagaribi model new orders userId:integer productId:integer quantity:integer
pnpm run db:generate
pnpm run db:migrate
Edit packages/orders/src/index.ts with routes and logic.
npx kagaribi dev
curl http://localhost:3000/api/orders
curl -X POST http://localhost:3000/api/orders \
-H "Content-Type: application/json" \
-d '{"userId":1,"productId":42,"quantity":2}'
export type XxxApp = typeof appcreateDbMiddleware() for consistent DB accesskagaribi.package.tsIssue: RPC call fails with "Package not found"
dependencies array in kagaribi.package.tsIssue: Database queries fail
createDbMiddleware({ initFn: initDb }) is applied before routesIssue: TypeScript error on getClient<T>()
export type XxxApp = typeof app)Issue: Model generation fails
npx kagaribi init --db <dialect> first to set up database supportIssue: Changes not reflected
npx kagaribi dev server (hot reload not yet supported)After development: