---
title: ESM Dynamic Loading
slug: features/esm-dynamic-loading
icon: box-open
description: Load npm packages at runtime as MCP apps with caching and auto-update
keywords: ['frontmcp', 'mcp', 'model context protocol', 'features', 'framework', 'esm', 'dynamic loading', 'typescript']
---

FrontMCP can **dynamically load npm packages at runtime** and register their tools, resources, and prompts alongside your local apps. Packages are fetched from a CDN, cached locally (memory + disk), and executed in-process — with optional background polling for automatic updates.

## Three App Types

FrontMCP supports three ways to compose apps:

| Type | Declaration | Execution | Use Case |
|------|------------|-----------|----------|
| **Local** | `@App` class | In-process | First-party code you own |
| **ESM Package** | `App.esm()` | In-process | Community or internal npm packages |
| **Remote** | `App.remote()` | HTTP proxy | External MCP servers |

```ts
import { FrontMcp, App } from '@frontmcp/sdk';

@FrontMcp({
  info: { name: 'Platform', version: '1.0.0' },
  apps: [
    CrmApp,                                        // Local app
    App.esm('@acme/analytics@^2.0.0'),             // ESM package
    App.remote('https://ext.example.com/mcp'),     // Remote app
  ],
})
export default class Server {}
```

## Key Capabilities

1. **Dynamic Loading** — Import npm packages at server startup via `App.esm()` without bundling them into your build
2. **Two-Tier Caching** — In-memory + disk cache with configurable TTL for fast startup and offline resilience
3. **Version Polling** — Background semver-aware polling with automatic hot-reload when new versions are published
4. **Private Registries** — Token-based authentication for private npm registries and custom CDN endpoints
5. **Browser Support** — Same `App.esm()` API works in browser environments with in-memory-only caching

## Minimal Example

```ts
import { FrontMcp, App } from '@frontmcp/sdk';

@FrontMcp({
  info: { name: 'My Server', version: '1.0.0' },
  apps: [
    App.esm('@acme/mcp-tools@^1.0.0', {
      namespace: 'acme',
      autoUpdate: { enabled: true },
    }),
  ],
})
export default class Server {}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="ESM Packages Reference" icon="box-open" href="/frontmcp/servers/esm-packages">
    Full API reference for App.esm(), caching, auth, and configuration
  </Card>
  <Card title="Publishing ESM Packages" icon="box-archive" href="/frontmcp/guides/publishing-esm-packages">
    Create and publish npm packages loadable by FrontMCP servers
  </Card>
  <Card title="CLI Reference" icon="terminal" href="/frontmcp/getting-started/cli-reference">
    Manage ESM packages with `frontmcp package esm-update`
  </Card>
  <Card title="ESM Errors" icon="triangle-exclamation" href="/frontmcp/sdk-reference/errors/esm-errors">
    Error classes for loading, caching, and authentication failures
  </Card>
</CardGroup>
