Skip to main content
This guide will help you get started with Nile Auth and ElysiaJS. This guide outlines the steps required to configure and integrate authentication in your application.
If you have not done so yet, be sure you have obtained credentials from the console.
1

Install packages

  bun add @niledatabase/server @niledatabase/elysia elysia
2

Configure the extension

The simplest way to use Nile with Elysia is to register the extension. This will automatically mount Nile’s default API routes (authentication, tenant management, etc.) onto your Elysia application.
app.ts
import { Elysia } from 'elysia';
import { Nile } from '@niledatabase/server';
import { elysia } from '@niledatabase/elysia';

const app = new Elysia();

// Initialize Nile with the Elysia extension
const nile = Nile({
  extensions: [elysia(app)],
});

// The extension has now registered routes like:
// POST /api/auth/signin
// POST /api/auth/signup
// GET  /api/auth/session
// ...and more

app.listen(3000);

console.log(
  `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`,
);

Custom Authentication Plugin

For a more idiomatic Elysia experience, you can create a plugin that derives the authenticated user and exposes helper methods. This allows you to access the user directly in your handlers using destructuring.
import { Elysia } from 'elysia';
import { Nile } from '@niledatabase/server';
import { elysia } from '@niledatabase/elysia';

const app = new Elysia();
const nile = Nile({
  extensions: [elysia(app)],
});

// Create a plugin that derives the user for every request
const authPlugin = (app: Elysia) =>
  app.derive(async ({ request }) => {
    // 1. Create headers from the incoming request to propagate cookies/auth
    const headers = new Headers(request.headers);

    // 2. Use nile.withContext to ensure the SDK uses these headers
    const user = await nile.withContext({ headers }, async (nileCtx) => {
      return await nileCtx.auth.getSession();
    });

    return {
      Auth: {
        user,
        // Wrap SDK methods to automatically provide context
        signUp: async (email: string, password: string) => {
          return nile.withContext({ headers }, (c) =>
            c.auth.signUp({ email, password }),
          );
        },
        signIn: async (email: string, password: string) => {
          return nile.withContext({ headers }, (c) =>
            c.auth.signIn('credentials', { email, password }),
          );
        },
      },
    };
  });
Now you can use the plugin in your application and access Auth.user directly.
app
  .use(authPlugin)
  .get('/profile', ({ Auth: { user }, error }) => {
    if (!user) {
      return error(401, 'Not Authenticated');
    }
    return user;
  })
  .post('/register', async ({ Auth, body }) => {
    const { email, password } = body as any;
    return await Auth.signUp(email, password);
  });

app.listen(3000);

Context Awareness

The @niledatabase/elysia extension automatically handles context for the built-in routes it registers. However, for custom routes, you need to manually provide the context if your logic depends on Nile (e.g., querying the DB with tenant isolation or performing Auth operations).
app.get('/my-data', async ({ request }) => {
  const headers = new Headers(request.headers);
  // Extract tenantId from headers, query params, or URL path as needed
  const tenantId = request.headers.get('X-Tenant-Id') || undefined;

  return await nile.withContext({ headers, tenantId }, async (nileCtx) => {
    // This query will automatically apply the tenantId for the tenant-aware table
    const result = await nileCtx.db.query('SELECT * FROM my_table');
    return result.rows;
  });
});

The extension

Under the hood, the elysia extension does the following:
  1. Maps Nile’s handlers and paths to Elysia’s router (e.g. app.get, app.post).
  2. Intercepts requests using onHandleRequest to detect Elysia contexts.
  3. Automatically propagates request headers and tenant IDs into the Nile context for safe, isolated execution.

Handlers and paths

The extension iterates over the configured paths in the Nile Server SDK and registers them directly with your Elysia app instance. This ensures that all standard authentication and tenant management routes are available without manual configuration.

Context Management

For requests handled by the extension, it wraps the execution in nile.withContext. This ensures that nile.db and nile.auth calls within those handlers automatically respect the current tenant and user session, applying necessary authorization policies.