xTaskjs 1.0 is live: role-based accounts, documentation, and a customizable interface.

Samples

Official example applications for core, adapters, persistence, caching, scheduling, and queues.

Use the sample applications as the shortest route into the framework. They show the main runtime combinations shipped in the upstream monorepo, including mailer, cache, scheduler, and queue-focused samples, and the endpoints each one exposes.

22 reference samples documented

Start small

Use 01-new_app to understand the minimal node-http bootstrap and route registration flow.

Swap adapters

Compare Express and Fastify samples to see how controllers stay stable while the server changes.

Add integrations

Move into the TypeORM, security, mailer, cache, scheduler, and queues samples when you need persistence, protected routes, background work, or asynchronous delivery workflows.

Catalog

Reference applications shipped in the monorepo

samples/01-new_app

01-new_app

Smallest possible application. It proves that core can boot a server and route a health endpoint with no external adapter.

node-http + core

Endpoints

  • GET /health

Typical flow

  1. Install dependencies inside the sample folder.
  2. Run npm start to boot CreateApplication() with node-http.
  3. Call /health to verify controller registration and logger wiring.

samples/02-express_app

02-express_app

Shows how an existing Express app is wrapped by ExpressAdapter while controllers still return framework-native values.

core + express-http

Endpoints

  • GET /
  • GET /health

Typical flow

  1. Create an Express instance and enable body parsing or other middleware yourself.
  2. Pass the instance into new ExpressAdapter(expressApp).
  3. Render a template-backed home page and expose a JSON health endpoint.

samples/03-fastify_app

03-fastify_app

Demonstrates adapter portability: the same controller style runs on Fastify without changing business logic.

core + fastify-http

Endpoints

  • GET /
  • GET /health

Typical flow

  1. Create a Fastify instance with its own logger/runtime options.
  2. Wrap it with FastifyAdapter.
  3. Reuse the same controller conventions used by Express and node-http.

samples/04-typeorm_app

04-typeorm_app

Adds persistent state on top of the Fastify adapter. The sample seeds users and demonstrates datasource lifecycle registration.

fastify-http + typeorm

Endpoints

  • GET /users/
  • POST /users/seed
  • GET /health/

Typical flow

  1. Decorate a datasource configuration class with TypeOrmDataSource().
  2. Boot the app with FastifyAdapter.
  3. Use injected repositories or datasources inside services to query and mutate state.

samples/06-security_app

06-security_app

Demonstrates JWT and JWE flows without a full web framework adapter, focusing on strategy registration and protected controllers.

node-http + security

Endpoints

  • GET /health/
  • GET /auth/jwt/admin
  • GET /me/
  • GET /admin/
  • GET /encrypted/

Typical flow

  1. Register JWT and JWE strategies before CreateApplication().
  2. Issue a demo token from /auth/jwt/admin.
  3. Use Authorization: Bearer <token> against /me/ and /admin/.

samples/07-security_express_app

07-security_express_app

Combines Express integration with security decorators and the mailer module, showing authenticated profile endpoints plus protected transactional and notification emails.

express-http + security + mailer

Endpoints

  • GET /health/
  • GET /auth/jwt/admin
  • GET /me/
  • POST /me/notify
  • GET /admin/
  • GET /encrypted/

Typical flow

  1. Create an Express app, register JWT and JWE strategies, then register mail transports and templates at startup.
  2. Fetch a demo token from /auth/jwt/admin and call /me/ with Authorization: Bearer <token>.
  3. POST to /me/notify to render profile email templates and deliver through the default and notifications transports.

samples/08-email_express_app

08-email_express_app

Dedicated mailer sample showing named transports, EJS-backed email templates, and DI-managed services that send welcome and campaign messages.

express-http + mailer

Endpoints

  • GET /health/
  • GET /email/
  • POST /email/welcome
  • POST /email/campaign

Typical flow

  1. Register the default and notifications transports, then attach the ejs-file renderer and email templates.
  2. Start the Express app through CreateApplication() and inspect /email/ for the sample contract.
  3. POST to /email/welcome or /email/campaign to render templates and send through the configured transporter.

samples/09-internationalization_app

09-internationalization_app

Shows request-scoped locale resolution, translation helpers, custom formatters, and lazy namespace loading on the default node-http adapter.

node-http + internationalization

Endpoints

  • GET /health
  • GET /i18n
  • GET /i18n?locale=es-ES&name=ada&items=3&amount=1499.95
  • GET /i18n/checkout?locale=en-US&items=2&amount=249.5

Typical flow

  1. Configure default locale, fallback locale, and built-in formatters before CreateApplication().
  2. Open /i18n to inspect translated messages, locale state, and loaded namespaces.
  3. Hit /i18n/checkout to trigger lazy namespace loading and localized number, currency, and datetime formatting.

samples/10-internationalization_express_app

10-internationalization_express_app

Combines localized page rendering with the Express adapter, including query-driven locale switching, Accept-Language support, and lazy checkout translations.

express-http + internationalization

Endpoints

  • GET /?locale=en-US&name=ada&items=3&amount=1499.95
  • GET /?locale=es-ES&name=ada&items=3&amount=1499.95
  • GET /checkout?locale=es-ES&name=ada&items=2&amount=249.5
  • GET /health

Typical flow

  1. Configure locale catalogs and custom formatters, then boot an Express app through ExpressAdapter.
  2. Open the localized home page and switch between en-US and es-ES through query parameters or Accept-Language.
  3. Follow the checkout route to exercise lazy namespace loading with server-rendered views.

samples/11-scheduler_app

11-scheduler_app

Demonstrates scheduled jobs integrated with xtask lifecycle, including boot execution, named groups, retries, and runtime inspection endpoints.

node-http + scheduler

Endpoints

  • GET /health
  • GET /scheduler/status
  • GET /scheduler/groups
  • GET /scheduler/run-maintenance

Typical flow

  1. Start the sample to let CreateApplication() discover scheduled methods after the container boots.
  2. Open /scheduler/status to inspect job metadata, counters, failures, and recent events.
  3. Call /scheduler/run-maintenance to trigger a named job group manually and observe retry behavior.

samples/12-cache_app

12-cache_app

Introduces cache models, method decorators, repository injection, and the built-in cache management controller on the default node-http adapter.

node-http + cache

Endpoints

  • GET /cache/products/:id
  • GET /cache/products/:id/inspect
  • GET /cache/products/:id/refresh
  • GET /cache/products/:id/evict
  • GET /ops/cache/models

Typical flow

  1. Configure the cache package with memory storage defaults and register a ProductCacheModel before CreateApplication().
  2. Call the product, refresh, and evict endpoints to observe Cacheable, CachePut, and CacheEvict behavior.
  3. Inspect /ops/cache/models and /cache/products/:id/inspect to verify repository state and generated admin metadata.

samples/13-cache_redis_app

13-cache_redis_app

Switches the same caching model to Redis so the decorators and repository APIs stay the same while storage moves out of process.

node-http + cache + redis

Endpoints

  • GET /cache/products/:id
  • GET /cache/products/:id/inspect
  • GET /cache/products/:id/refresh
  • GET /cache/products/:id/evict
  • GET /ops/cache/models

Typical flow

  1. Configure a Redis-backed cache model or client factory before boot so the lifecycle manager can open the store.
  2. Reuse the same service decorators and repository injection patterns from the memory sample.
  3. Use the inspect and admin endpoints to confirm Redis-backed entries, TTL behavior, and explicit eviction paths.

samples/14-http_cache_web_app

14-http_cache_web_app

Shows browser-facing cache policies on rendered pages and JSON endpoints, including ETag, Last-Modified, stale-while-revalidate, and preview no-store behavior.

express-http + cache

Endpoints

  • GET /
  • GET /articles/:slug
  • GET /api/articles/:slug
  • GET /preview
  • GET /ops/cache/http/routes

Typical flow

  1. Define package-wide httpCacheDefaults and then override them per route with CacheView, BrowserCache, and NoStore decorators.
  2. Request the same pages with conditional headers to observe ETag and Last-Modified handling on cached responses.
  3. Inspect /ops/cache/http/routes to verify the effective Cache-Control policy and validators resolved for each route.

samples/15-fastify_http_cache_web_app

15-fastify_http_cache_web_app

Ports the browser cache sample to Fastify to show that the same cache decorators and admin controller work across adapters.

fastify-http + cache

Endpoints

  • GET /
  • GET /articles/:slug
  • GET /api/articles/:slug
  • GET /preview
  • GET /ops/cache/http/routes

Typical flow

  1. Boot the app through FastifyAdapter while keeping the same CacheView, BrowserCache, NoStore, and management-controller setup.
  2. Compare the page and API endpoints with the Express version to confirm adapter-portable HTTP cache behavior.
  3. Use the admin routes to inspect merged cache policy, validators, and route metadata under Fastify as well.

samples/16-queues_memory_app

16-queues_memory_app

Introduces the queues package with the built-in in-memory transport, decorated consumers, pattern listeners, and publish-on-return workflows.

node-http + queues

Endpoints

  • GET /queues/
  • GET /queues/status
  • POST /queues/orders
  • POST /queues/orders/:id/complete

Typical flow

  1. Configure configureQueues() with an explicit memory transport and registerInMemoryQueueTransport() before CreateApplication().
  2. POST to /queues/orders to publish a message and watch QueueHandler and QueuePattern consumers update the in-memory event log.
  3. POST to /queues/orders/:id/complete to exercise PublishToQueue() and observe chained local queue workflows.

samples/17-queues_rabbitmq_app

17-queues_rabbitmq_app

Moves the same queue model to RabbitMQ, adding topic routing, competing consumers, retries, and dead-letter handling through the broker helper.

node-http + queues + rabbitmq

Endpoints

  • GET /health
  • GET /queues/
  • GET /queues/status
  • POST /queues/orders
  • POST /queues/orders/:id/fail
  • POST /queues/orders/:id/complete

Typical flow

  1. Configure the default transport with createRabbitMqTransport() and registerQueueTransport() before CreateApplication().
  2. Publish orders through /queues/orders and /queues/orders/:id/fail to inspect retries, audit listeners, and dead-letter routing.
  3. Open /queues/status to inspect started consumers, transport metadata, groups, retry settings, and recent events.

samples/19-cqrs_app

19-cqrs_app

Shows a full CQRS flow with separate SQLite write and read databases, injected buses, idempotent commands, event-driven projections, and projection rebuild support.

node-http + typeorm + cqrs

Endpoints

  • GET /cqrs/
  • GET /cqrs/users
  • GET /cqrs/debug/state
  • POST /cqrs/users
  • POST /cqrs/users/:id/onboard
  • POST /cqrs/projections/rebuild

Typical flow

  1. Register two TypeORM datasources and bind them to @Cqrs(...) as write-db and read-db before CreateApplication().
  2. Use CommandBus and QueryBus from the controller to create users, inspect read models, and trigger onboarding commands.
  3. Inspect /cqrs/debug/state and POST /cqrs/projections/rebuild to verify projection handlers, rebuilders, and read-model synchronization.

samples/20-cqrs_postgres_replication_app

20-cqrs_postgres_replication_app

Extends the CQRS sample to Postgres master and replica datasources so writes stay on the primary, reads come from the replica, and projection rebuild tooling remains part of the same lifecycle.

node-http + typeorm + cqrs + postgres

Endpoints

  • GET /cqrs/
  • GET /cqrs/users
  • GET /cqrs/debug/state
  • POST /cqrs/users
  • POST /cqrs/users/:id/rename
  • POST /cqrs/projections/rebuild

Typical flow

  1. Configure @xtaskjs/typeorm datasources for pg-master and pg-slave, then point @Cqrs(...) at those aliases before bootstrap.
  2. Route write-side commands through CommandBus while query handlers and injected read repositories use the replica datasource.
  3. Use the debug and rebuild endpoints to inspect replication-aware state, registered projection rebuilders, and lifecycle-managed read-model recovery.

samples/21-event_source_rabbitmq_app

21-event_source_rabbitmq_app

Demonstrates event-sourced aggregate writes backed by a SQLite event store, in-process projection updates, and RabbitMQ publication of stored domain events.

node-http + event-source + typeorm + queues + rabbitmq

Endpoints

  • GET /health
  • GET /event-source/
  • GET /event-source/users
  • GET /event-source/streams/:id
  • GET /event-source/status
  • POST /event-source/users
  • POST /event-source/users/:id/verify-email

Typical flow

  1. Configure @EventSource(...) with createTypeOrmEventStore() and createQueueEventPublisher(), then register a RabbitMQ transport before CreateApplication().
  2. Create and evolve aggregates through the POST endpoints, then inspect /event-source/streams/:id to verify replayed state and persisted event history.
  3. Open /event-source/status to inspect projection counts, started queue consumers, registered transports, and broker audit information.

samples/22-event_source_cqrs_app

22-event_source_cqrs_app

Shows the package boundary where event-source owns aggregate writes and stream persistence while CQRS builds and queries a separate read model.

node-http + event-source + typeorm + cqrs

Endpoints

  • GET /health
  • GET /interop/
  • GET /interop/users
  • GET /interop/state
  • GET /interop/streams/:id
  • POST /interop/users
  • POST /interop/users/:id/verify-email

Typical flow

  1. Register the event-store datasource and the separate read datasource, then bind event-source and CQRS to those aliases before bootstrap.
  2. Create users through the event-source endpoints and inspect /interop/streams/:id to confirm aggregate replay and stored event history.
  3. Query /interop/users and /interop/state to verify CQRS projections, runtime state, and the read-side model fed from persisted domain events.

samples/23-socket_io_express_app

23-socket_io_express_app

Express sample application using decorated Socket.IO gateways, room joins, automatic acknowledgements, and HTTP-triggered broadcasts.

express-http + socket-io

Endpoints

  • GET /
  • GET /health
  • GET /socket/
  • GET /socket/status
  • GET /socket/announce/:message

Typical flow

  1. Boot Express through ExpressAdapter and let @xtaskjs/socket-io attach to the live HTTP server during listen().
  2. Open the demo page, join the /chat namespace lobby, and emit chat.join plus chat.message events from the browser client.
  3. Call /socket/announce/:message to publish a server.announcement event from an HTTP controller through InjectSocketService().

samples/24-throttler_app

24-throttler_app

node-http application demonstrating global and per-endpoint rate limiting using configureThrottler and @Throttle decorators with memory storage.

node-http + throttler

Endpoints

  • GET /health
  • GET /items (throttled: 10 req / 30s)
  • GET /items/heavy (throttled: 2 req / 1m)
  • GET /items/open (no throttle)

Typical flow

  1. configureThrottler() registers global 100 req/min default with memory driver.
  2. Request arrives at a throttled endpoint.
  3. Throttler extracts the key (IP by default) and checks the counter in the store.
  4. Within limit: request proceeds normally to the controller handler.
  5. Over limit: 429 Too Many Requests is returned with a Retry-After header.