Skip to main content
Tanxium is Yasumu’s custom JavaScript runtime built on deno_runtime. It handles all backend logic including request execution, database operations, scripting, and the internal RPC server.

What is Tanxium?

Tanxium is a custom JavaScript runtime embedded directly into the Tauri application. Unlike traditional approaches that run Node.js or Deno as a separate process, Tanxium:
  • Runs in the same process as the Tauri app
  • Provides a sandboxed environment for user scripts
  • Offers custom APIs specific to Yasumu’s needs
  • Eliminates the need for users to install Node.js or Deno

Architecture overview

Core components

Tanxium consists of several key components:

1. Deno runtime integration

Tanxium is built on Deno’s runtime libraries:
# From Cargo.toml
deno_runtime = { version = "0.229.0", features = ["transpile", "snapshot"] }
deno_core = "0.363.0"
deno_fs = "0.131.0"
deno_resolver = "0.52.0"
deno_ast = { version = "0.51.0", features = ["transpiling"] }
This provides:
  • TypeScript support: Native TypeScript execution without build steps
  • Web APIs: Standard fetch, Request, Response, etc.
  • V8 engine: The same JavaScript engine that powers Chrome
  • Module resolution: ESM imports with npm package support

2. Custom Yasumu APIs

Tanxium exposes a global Yasumu object with custom APIs:
/// <reference types="yasumu:types" />

// Available in all Tanxium scripts:
Yasumu.getServerEntrypoint()  // Get the runtime directory
Yasumu.setRpcPort(port)        // Set the RPC server port
Yasumu.setEchoServerPort(port) // Set the SMTP server port
These APIs bridge Tanxium and the Tauri shell, allowing the runtime to communicate state back to the native layer.

3. RPC server

The RPC server is a Hono application that handles frontend requests:
import { Hono } from 'hono';

export const rpcServer = new Hono()
  .post('/rpc', async (c) => {
    const { command, parameters, type } = await c.req.json();
    
    // Route command to appropriate handler
    const handler = commandHandlers[command];
    const result = await handler(...parameters);
    
    return c.json({ result });
  });
The server:
  • Listens on a random port (0 = OS assigns)
  • Accepts JSON-RPC style requests
  • Routes commands to registered handlers
  • Returns type-safe responses

4. Database layer

Tanxium uses SQLite with Drizzle ORM:
import { drizzle } from 'drizzle-orm/sqlite3';
import Database from 'better-sqlite3';

const sqlite = new Database('./yasumu.db');
export const db = drizzle(sqlite);
Schema management:
  • Tables defined in TypeScript with Drizzle schemas
  • Migrations generated with drizzle-kit generate
  • Migrations run automatically on startup

5. SMTP echo server

The echo server catches test emails:
import { SMTPServer } from 'smtp-server';

export const echoServer = new SMTPServer({
  authOptional: true,
  onData: async (stream, session, callback) => {
    // Parse email and store in database
    const email = await parseEmail(stream);
    await db.insert(emails).values(email);
    callback();
  }
});
This allows developers to test email functionality without configuring external SMTP servers.

Startup sequence

When Tauri launches, Tanxium goes through this initialization:

Step-by-step

  1. Worker creation: Tauri creates a Deno worker thread
  2. Module loading: Loads main.ts from the resources directory
  3. Migration: Runs database migrations via Drizzle
  4. Server start: Starts RPC and echo servers on random ports
  5. Port registration: Communicates ports back to Tauri
  6. Ready: Frontend can now make RPC calls

Request execution flow

When executing a REST API request:

Pre-request scripts

Pre-request scripts run before the HTTP request:
// Pre-request script example
const token = await fetchAuthToken();
yasumu.setVariable('authToken', token);
These scripts can:
  • Set variables for the request
  • Make additional HTTP calls
  • Read from the database
  • Generate dynamic data

Post-request scripts

Post-request scripts run after receiving the response:
// Post-request script example
const data = await response.json();
yasumu.expect(data.status).toBe('success');
yasumu.setVariable('userId', data.id);
These scripts can:
  • Run assertions/tests
  • Extract data from responses
  • Chain requests together
  • Update the database

Module system

Tanxium supports both ESM and npm packages:

Built-in modules

// Node compatibility layer
import { join } from 'node:path';
import { readFile } from 'node:fs/promises';

// Web APIs
import { fetch } from 'fetch';

npm packages

// npm: specifier for npm packages
import { z } from 'npm:zod';
import lodash from 'npm:lodash';

Workspace packages

Tanxium can import from the Yasumu workspace:
import { YasumuRPC } from '@yasumu/rpc';
import { WorkspaceManager } from '@yasumu/core';
These are bundled at build time using Deno’s bundler.

Bundling process

Tanxium’s source code is bundled into a single JavaScript file:
# Build command (packages/tanxium/package.json)
deno task bundle
The bundler:
  1. Resolves all imports (workspace packages, npm packages)
  2. Transpiles TypeScript to JavaScript
  3. Bundles into a single main.ts file
  4. Copies to Tauri’s resources directory
This ensures:
  • Fast startup (no module resolution at runtime)
  • Single artifact to embed
  • No external dependencies

Permissions and security

Tanxium implements a permission system for user scripts:

Permission types

  • Network: Making HTTP requests
  • Filesystem: Reading/writing files
  • Environment: Accessing environment variables
  • Command: Running system commands

Permission prompts

When a script requests a sensitive operation:
// User script wants to read a file
const content = await Deno.readTextFile('./config.json');
  1. Tanxium pauses execution
  2. Sends permission request to Tauri
  3. Tauri shows native dialog to user
  4. User approves/denies
  5. Response sent back to Tanxium
  6. Script continues or throws error

Virtual modules

Tanxium supports “virtual modules” that don’t exist on disk:
// Tauri can inject modules at runtime
pub struct YasumuInternalState {
    pub virtual_modules: VirtualModulesStore,
}

// Virtual module content
virtual_modules.insert(
    "yasumu:config".to_string(),
    "export const appVersion = '0.1.0';".to_string()
);
Scripts can then import these:
import { appVersion } from 'yasumu:config';
This is useful for:
  • Injecting runtime configuration
  • Providing platform-specific APIs
  • Dynamic code generation

Performance optimizations

Tanxium is optimized for fast startup and execution:

Snapshots

deno_runtime = { version = "0.229.0", features = ["snapshot"] }
Deno snapshots serialize the V8 heap after loading standard libraries, reducing startup time from ~100ms to ~10ms.

Lazy loading

Large dependencies are imported lazily:
// Only import when needed
if (needsSMTP) {
  const { SMTPServer } = await import('smtp-server');
}

Connection pooling

Database connections are pooled and reused:
const db = drizzle(sqlite); // Single connection

Debugging

Developers can inspect Tanxium using Chrome DevTools:
  1. Enable devtools in development mode
  2. Use console.log() from scripts
  3. Logs appear in both Tauri logs and DevTools console
// In user script
console.log('Pre-request:', { url, headers });

Next steps

Build docs developers (and LLMs) love