Development Guide

Folder Structure

Folder structure, file naming conventions, and how Reion maps files to routes, middleware, security, and events.

This guide explains how Reion organizes your appDir directory: which folders and file names are special, how URL paths are derived, and how to name files for routes, middleware, security.ts, and events.


App folder structure

All application code that Reion loads lives under a single appDir (by default ./src, configurable via reion.config.ts). The layout looks like this:

reion.config.ts
package.json
  • Routes — Route files live under router/; the folder path under router/ becomes the URL path.
  • Middlewarerouter/**/middleware.ts (or .js/.mts/.mjs) applies to that directory and all subpaths (prefix is relative to router/).
  • Securityrouter/**/security.ts (or .js/.mts/.mjs) attaches route-level security config for that path prefix; see Security.
  • Events — Files under appDir/events/ (including nested folders) are loaded as event handlers.

Route file naming

Reion treats two kinds of files as route handlers:

1. Single file for all methods: route.ts

  • Names: route.ts, route.js, route.mts, route.mjs
  • Meaning: This path handles every HTTP method you implement (e.g. GET, POST).
  • Exports: Export a function per method: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, and/or default (used when the request method doesn't have its own export).

Example: router/api/posts/route.ts → serves /api/posts for any method you export.

2. One file per method: get.ts, post.route.ts, etc.

  • Names: get.ts, post.ts, get.route.ts, post.route.ts, etc. (same for put, patch, delete, head, options).
  • Extensions: .ts, .js, .mts, .mjs
  • Meaning: That path handles only that HTTP method. You can mix: e.g. route.ts for GET and post.route.ts for POST on the same path.
  • Exports: Export the handler as the method name (e.g. export function GET) or as default.

You cannot have two files that both handle the same method for the same path (e.g. two files for GET on /api/users); the loader will throw.


How URL paths are built

  • The pathname of a route is the directory path to the folder that contains the route file. The filename does not appear in the URL.
  • Route groups — A folder whose name is in parentheses is omitted from the URL:
    • router/api/(user)/users/route.ts → pathname is /api/users (not /api/(user)/users).
  • Dynamic segments — A folder whose name is in square brackets becomes a path parameter:
    • router/api/posts/[postId]/route.ts → pathname /api/posts/:postId; the matched value is in ctx.params.postId.
  • Optional catch-all[[...param]] matches the rest of the path (including zero segments). The param name (e.g. all) receives the remainder as a single string.

Examples:

File pathURL path
router/route.ts/
router/api/hello/route.ts/api/hello
router/api/(user)/users/get.route.tsGET /api/users
router/api/(user)/posts/[postId]/route.ts/api/posts/:postId
router/api/(user)/posts/[postId]/author/route.ts/api/posts/:postId/author

Middleware file naming

  • Names: middleware.ts, middleware.js, middleware.mts, middleware.mjs
  • Placement: Only under router/. The directory path under router/ is the path prefix for which the middleware runs. Middleware in a folder runs for that path and all subpaths.
  • Order: Middleware is resolved from the root toward the request path (e.g. router/middleware.ts then router/api/middleware.ts for a request to /api/hello).

Security file naming: security.ts

Use router/**/security.ts (or .js / .mts / .mjs) for path-scoped policies. Naming, exports, merging along the URL, and route-group caveats are covered in the Security guide.


Event handlers: appDir/events/

  • Directory: appDir/events/ is scanned recursively for event handlers.
  • File names: *.event.ts, *.event.js, *.event.mts, *.event.mjs, or plain *.ts / *.js / *.mts / *.mjs under events/.
  • Event name: Each folder segment and the file basename (before the extension) are converted camelCase → dot.case, then joined with dots (e.g. billing/invoicePaid.event.tsbilling.invoice.paid; userCreatedEmail.event.tsuser.created.email).
  • Export: The file must export a default function; that function is registered for the derived event name. Emit from routes with ctx.emit('event.name', payload).

Config and extensions summary

KindLocationFile patternNotes
RoutesAny folder under router/route.ts, get.ts, post.route.ts, etc.Folder path under router/ = URL path; (group) omitted, [id] = param
MiddlewareAny folder under router/middleware.tsPath prefix = directory path under router/
SecurityAny folder under router/security.tsPath prefix = directory path under router/; merged along URL ancestor prefixes — see Security
EventsappDir/events/ (recursive)*.event.ts, *.ts, etc.Event name = path segments + basename, each camelCase → dot.case

Supported extensions for routes, middleware, and security: .ts, .js, .mts, .mjs. Use the same extensions for event files.


Next steps

  • Get Started — Set up a project and run your first route.
  • Routing — Dynamic segments, route groups, and method handlers in more detail.
  • Middleware — Order, next(), and error handling.
  • Securityrouter/**/security.ts for rate limits, headers, CSRF, etc. (Security).