AbsoluteJS

Plugin Composition

Compose Elysia plugins directly in AbsoluteJS with clear boundaries and predictable hook behavior.

#Basics

Stack plugins in the same Elysia chain:

TS
import { Elysia } from 'elysia';
import { cors } from '@elysiajs/cors';
import { swagger } from '@elysiajs/swagger';
import { staticPlugin } from '@elysiajs/static';

new Elysia()
  .use(cors())
  .use(swagger())
  .use(staticPlugin({ assets: './public' }));

#Encapsulation

Use sub-plugins to isolate API and background job behavior:

TS
import { Elysia } from 'elysia';
import { cors } from '@elysiajs/cors';
import { cron } from '@elysiajs/cron';

const apiPlugin = new Elysia({ prefix: '/api' })
  .use(cors({ origin: ['https://app.example.com'] }))
  .get('/health', () => ({ ok: true }));

const jobsPlugin = new Elysia({ prefix: '/jobs' })
  .use(
    cron({
      name: 'heartbeat',
      pattern: '*/30 * * * * *',
      run() {
        console.log('background heartbeat');
      }
    })
  );

new Elysia()
  .use(apiPlugin)
  .use(jobsPlugin);

#Scoped Hooks

Hooks defined in a plugin apply to routes in that plugin scope:

TS
import { Elysia } from 'elysia';

const authPlugin = new Elysia({ prefix: '/app' })
  .onBeforeHandle(({ cookie, status }) => {
    if (!cookie.session?.value) {
      return status(401, 'Unauthorized');
    }
  })
  .get('/dashboard', () => 'private');

new Elysia()
  .get('/', () => 'public')
  .use(authPlugin);

#Registration Order

Registration order determines what hooks and plugins apply to each route:

TS
import { Elysia } from 'elysia';
import { cors } from '@elysiajs/cors';
import { swagger } from '@elysiajs/swagger';

new Elysia()
  .use(cors())
  .use(swagger())
  // register routes after plugins/hooks you want applied
  .get('/api/users', () => [])
  .listen(3000);
Plugin before routePlugin behavior applies
Plugin after routeExisting route is unaffected

#References