Front door: index.ts
Path: hono-backend/src/index.ts
This is the first file that runs when the Node process starts (after TypeScript compiles).
What it does in order
import 'dotenv/config'— load.envintoprocess.env.- Create
app = new Hono<HonoEnv>()— empty web application with typed context. - CORS middleware — which browser origins may call us (vite dev ports +
ALLOWED_ORIGIN+chrome-extension://*).credentials: trueandX-Request-Id/RateLimit-*/Retry-Afterare added toexposeHeaders. requestIdMiddleware— assign or honorX-Request-Idfor correlated logs.rateLimitMiddleware— dynamic quota check; fails open if the limiter itself errors.GET /health— liveness probe ({ status: 'ok' }).GET /ready— readiness probe; returns 503 untilmongoose.connection.readyState === 1, then{ status: 'ready', db: 'connected', requestId }.app.route(...)— attach each router at a URL prefix (see Route map).app.onError— last-resort error handler:ZodError→ 400{ error, code: 'VALIDATION_ERROR', requestId, details[] }(paths formatted withlib/format-zod-issue-path.ts).- any other error → 500
{ error, code: 'INTERNAL_ERROR', requestId }and a structuredlogServerError(...)call.
connectDB()thenserve({ port: env.PORT })— Mongo first, HTTP second.
Code idea (simplified)
const app = new Hono<HonoEnv>()
app.use('*', cors({ /* origins + expose headers */ }))
app.use('*', requestIdMiddleware)
app.use('*', rateLimitMiddleware)
app.get('/health', (c) => c.json({ status: 'ok' }))
app.get('/ready', (c) => readyOr503(c))
app.route('/api/v1/auth', authRouter)
// ... more routes ...
app.onError((err, c) => zodOr500(err, c))
connectDB().then(() => serve({ fetch: app.fetch, port: env.PORT }))Who imports what
| Import group | Files |
|---|---|
| Config | config/env.js, config/db.js |
| Middleware | middleware/request-id.middleware.js, middleware/rate-limit.middleware.js |
| Lib | lib/format-zod-issue-path.js, lib/logger.js |
| Types | types/index.js (HonoEnv) |
| Routes | routes/auth.route.js, routes/user.route.js, routes/admin.route.js, routes/admin-rate-limits.routes.js, routes/timestamps.route.js, routes/practice-pyq-public.routes.js, routes/current-affairs-public.routes.js, routes/notification.route.js (× 3 routers) |
Nothing in index.ts should contain business logic — only wiring.
If you add a new feature area
- Create
routes/my-feature.route.tsexporting aHono<HonoEnv>router. - Import it in
index.ts. app.route('/api/v1/my-feature', myFeatureRouter).- Document the prefix in Route map.
- If the surface is admin-only, also call
requirePermission(...)per-route so the right role can see it.
Read the real file in the repo — it has a long comment block at the top explaining the same story.
Last updated on