Browse documentation
DocumentationAvailable modules
MODULE CATALOG v0.1.0

Add what you need.

The modules available in the current published ExetJS toolkit.

The CLI 0.1.0 package includes a health module in every generated application and one installable template: auth. Both use the same ExetModule contract.

List installable templates
exet list

The list command reports auth. Health is already part of the generated app and is not a separate installable template. Core helpers such as validation and API responses belong to @exetjs/core.

Catalog verified against the templates and manifest in @exetjs/cli 0.1.0.

Health module #

exet init adds the module under src/modules/health/ and registers it in src/modules/index.ts. It has the name health and base path /health.

GET/api/v1/health200 OK
Request · example port 5000
curl http://localhost:5000/api/v1/health
Example response
{
  "success": true,
  "data": {
    "status": "ok",
    "engine": "ExetJS",
    "timestamp": "2026-09-19T12:00:00.000Z"
  }
}

The timestamp is created for each request. The actual endpoint follows your configured API prefix and port.

Generated health module
import type { ExetModule } from '@exetjs/core';
import { createHealthRouter } from './health.routes.js';

export const healthModule: ExetModule = {
  name: 'health',
  basePath: '/health',
  register: () => ({ router: createHealthRouter() }),
};

The route calls getHealth from health.controller.ts. This checks that the HTTP application is responding. It does not probe your database or external services; extend the module if you need dependency readiness checks.

Auth module #

The auth template installs editable source files into your application. It uses bcryptjs for password hashing, jsonwebtoken for JWTs, and Zod for request validation.

  • Register a user with a name, email and password.
  • Verify login credentials and return a signed token.
  • Resolve the current user from a bearer token.
  • Return a logout acknowledgement.
An authentication starting point.

The template uses an in-memory repository. Stored users disappear when the process restarts. Configure durable persistence and a strong JWT_SECRET before using it for a production application.

Installation & configuration #

Run the installer inside your generated ExetJS project. A dry run lets you inspect the intended changes first.

Install auth
exet install auth --dry-run
exet install auth

The CLI adds the template files, updates the module registry, adds the environment keys, updates dependencies, and installs those dependencies by default.

Environment configuration
# Replace this placeholder with a strong random secret.
JWT_SECRET=replace-with-your-generated-random-secret
JWT_EXPIRES_IN=1d

Set a non-empty secret. JWT_EXPIRES_IN defaults to 1d. The template has a development fallback and rejects a missing secret in production; do not rely on the fallback outside development.

Restart the development process after installing the module or changing its configuration.

Auth endpoints #

These paths use the default /api/v1 prefix. The module base path is /auth.

Method & pathInputResult
POST/api/v1/auth/registerName, email and password201 · public user
POST/api/v1/auth/loginEmail and password200 · user and JWT token
GET/api/v1/auth/meAuthorization: Bearer <token>200 · public user
POST/api/v1/auth/logoutNo request body required200 · loggedOut: true

Registration

name requires at least two characters, email must be valid, and password needs at least eight characters. An already registered email produces a 400 BAD_REQUEST error.

Login and current user

Invalid credentials produce 401 UNAUTHORIZED. The /me endpoint requires an Authorization: Bearer <token> header and rejects missing, invalid or expired tokens. Public user responses contain id, name, email, and createdAt; the password hash is excluded.

Request examples #

The following requests use an example local server on port 5000. Adjust the URL to your configured address.

Register
curl -X POST http://localhost:5000/api/v1/auth/register \
  -H 'Content-Type: application/json' \
  -d '{"name":"Alex Developer","email":"alex@example.com","password":"example-password-123"}'
Login
curl -X POST http://localhost:5000/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"alex@example.com","password":"example-password-123"}'

Read the token from data.token in the login response and use it for the authenticated request:

Current user
curl http://localhost:5000/api/v1/auth/me \
  -H 'Authorization: Bearer YOUR_TOKEN'
Logout
curl -X POST http://localhost:5000/api/v1/auth/logout
Logout response
{
  "success": true,
  "data": { "loggedOut": true }
}

Files & dependencies #

The installer adds eight files under src/modules/auth/ and two shared security helpers under src/shared/security/.

FileResponsibility
auth.module.tsComposes the repository, service, and router.
auth.routes.tsRegisters the four HTTP routes and request validation.
auth.controller.tsHandles HTTP input, responses, and bearer token extraction.
auth.service.tsRegistration, password checks, token creation, and current-user lookup.
auth.repository.tsIn-memory user storage and lookup methods.
auth.schema.tsZod registration and login schemas.
auth.types.tsStored user, public user, and token payload types.
index.tsExports authModule.
shared/security/password.tsbcryptjs hashing and password comparison.
shared/security/jwt.tsJWT signing and verification helpers.

Added runtime dependencies are bcryptjs and jsonwebtoken, with @types/jsonwebtoken as a development dependency. The template uses the generated project's existing Express, Zod, and Core dependencies.

The module composes the repository, service and router inside register(ctx). Its service receives ctx.logger; there is no dependency injection container.

Persistence & token behavior #

These are the behaviors of the published 0.1.0 template:

  • Users are held in a process-local Map. Multiple server processes do not share that state.
  • The repository exposes create, findByEmail and findById. Replace the implementation to connect your database.
  • Password hashing uses bcrypt with 12 salt rounds.
  • Tokens are signed with a user ID in sub and the user's email. Their lifetime follows JWT_EXPIRES_IN.
  • Logout returns an acknowledgement. It does not invalidate an already issued JWT. Remove the token from the client; add server-side revocation if your application needs it.
  • The template does not include refresh tokens, password reset, email verification, or roles and permissions.

Validation currently checks the auth request body, while its controller reads req.body. If you add transformations or defaults to the schemas, update your controller to use res.locals.validated, as shown in the Core validation guide.

Your own modules #

You can add application-specific modules without an installable template. Implement ExetModule, return an Express router, and register the module explicitly.

src/modules/index.ts · after installing auth
import type { ExetModule } from '@exetjs/core';
import { healthModule } from './health/health.module.js';
import { helloModule } from './hello/hello.module.js';

// exet:imports:start
import { authModule } from './auth/auth.module.js';
// exet:imports:end

export const modules: ExetModule[] = [
  healthModule,
  helloModule,
  // exet:modules:start
  authModule,
  // exet:modules:end
];

The example assumes you created the hello module from the getting started guide and installed auth. Keep the marker comments intact so future CLI installs can update the registry.

Understand the module lifecycleRead the Core contract