AbsoluteJS

State

State is a global mutable object shared across your Elysia app. Values assigned via .state() are added to the store property and remain accessible in all route handlers.

#Basic Usage

Use .state() to define values that will be available in the store object across all routes:

TS
// State is a global mutable object shared across the Elysia app
// Values assigned via .state() are added to the store property

import { Elysia } from 'elysia';

new Elysia()
  .state('version', 1)
  .state('counter', 0)
  .get('/version', ({ store: { version } }) => version)
  .get('/store', ({ store }) => store)
  .get('/increment', ({ store }) => {
    store.counter++;
    return store.counter;
  })
  .listen(3000);

#Type Safety

Elysia automatically infers types from your .state() calls. No explicit generics needed:

TS
// Elysia automatically infers types from .state() calls
// No explicit generics needed: TypeScript knows the shape

new Elysia()
  .state('count', 0)
  .state('name', 'app')
  .get('/', ({ store }) => {
    // store.count is number
    // store.name is string
    // store.unknown would be a TypeScript error
    return { count: store.count, name: store.name };
  });

#Mutation Gotcha

When mutating state, avoid destructuring primitive values. Destructuring creates a copy and breaks the reference to the original store:

TS
// ⚠️ IMPORTANT: Destructuring primitives breaks the reference!

new Elysia()
  .state('counter', 0)

  // ✅ Correct: maintains reference to store
  .get('/increment', ({ store }) => {
    store.counter++;
    return store.counter;
  })

  // ❌ Wrong: destructuring creates a copy of the primitive
  .get('/broken', ({ store: { counter } }) => {
    counter++;  // This only mutates the local copy!
    return counter;  // Returns incremented value but store is unchanged
  });

#State vs Decorate

Use .state() for mutable primitives and .decorate() for objects, classes, and utilities:

TS
// Use .state() for primitives you need to mutate
// Use .decorate() for non-primitive objects and classes

new Elysia()
  // State: mutable primitives shared across routes
  .state('requestCount', 0)
  .state('isMaintenanceMode', false)

  // Decorate: objects, classes, utilities
  .decorate('db', database)
  .decorate('logger', new Logger())

  .get('/stats', ({ store, db, logger }) => {
    store.requestCount++;
    logger.info('Stats requested');
    return db.query.stats.findFirst();
  });
.state()Mutable primitives like counters, flags, and configuration values
.decorate()Non-primitive objects like database connections, loggers, and service classes