A practical, friendly landing chapter for developers: concepts, structure, quickstart, and annotated examples.
Phantom is a lightweight developer platform and toolkit for building, documenting, and operating event-driven microservices and developer experiences. Think of it as a minimal, extensible runtime plus a rich documentation/SDK layer that helps teams ship APIs, background workers, and integrations with predictable patterns.
The goal of Phantom is to be opinionated where it helps (conventions, clear defaults) and flexible where it matters (plugin architecture, multiple language SDKs). This documentation set is designed for both newcomers and experienced engineers — it gives enough conceptual grounding to avoid costly mistakes while providing code-first examples for getting started quickly.
At its heart, Phantom embraces three principles:
Phantom reduces the time to first success by providing curated examples, a readable API surface, and a CLI scaffold generator. The documentation emphasizes "learn by doing" with progressive examples that scale from single-file demos to production-ready deployments.
Phantom uses small, composable components: event routers, worker runtimes, plugin drivers (for storage, messaging, observability). This predictable architecture helps teams reason about failure modes and scale horizontally as traffic grows.
Every core capability (auth, storage adapters, rate limiting) is implemented as an extension point. This keeps the runtime lean while enabling teams to replace or enhance behavior without hacking internals.
The Phantom platform consists of:
1. External event arrives (HTTP, webhook, message bus).
2. Phantom's router matches event to a handler based on configured rules.
3. Handler executes inside the runtime; the runtime enforces resource limits and secrets/credential injection.
4. Observability hooks emit traces and logs to configured sinks.
Plugins register capabilities (e.g., "storage", "kms", "pubsub"). Each plugin exposes a clear interface — a simple contract of methods and behaviors — so you can implement multiple providers while keeping the same developer surface.
The CLI is the quickest way to try Phantom locally. Install via npm:
npm install -g phantom-cli
phantom --version
Create a new project scaffold:
phantom new my-phantom-app
cd my-phantom-app
phantom dev
Drop this file in handlers/hello.js
:
module.exports = async function handle(event, ctx) {
// event.body, event.headers, event.params are available
return {
statusCode: 200,
body: JSON.stringify({message: "Hello from Phantom!", time: new Date().toISOString()})
};
};
curl -X POST http://localhost:8080/hello -d '{"name":"dev"}' -H "Content-Type: application/json"
You should see a JSON response from the handler. The local `phantom dev` command watches your source files and reloads handlers as you edit them.
Phantom places secrets into an isolated secret store and injects them at runtime as ephemeral credentials. Never check secrets into source control — use the CLI to set and rotate them:
phantom secrets set DB_PASSWORD --env=prod
phantom secrets rotate DB_PASSWORD --auto
Define minimal IAM roles for each handler. Phantom's role binding model encourages per-handler roles (not wide, cross-service keys).
Use private connectors for internal services. Phantom supports private endpoints and VPC-style attachment via the agent so that network traffic can stay within your cloud network.
Phantom supports configurable retry policies. Handlers should be idempotent or use deduplication keys when retries are possible. A typical pattern: store processed-message IDs in a short-lived dedupe store.
Logs are JSON by default. Each emitted log line includes requestId
, handler
, and trace metadata to join logs and traces quickly.
The `phantom dev` runtime provides a built-in debugger that can attach to handlers. Use breakpoints, inspect variables, and replay recorded events from the dev console.
Each handler should do one job: transform, validate, or orchestrate. For complex workflows, compose small handlers using a lightweight orchestrator plugin or event chaining.
Define input and output contracts (JSON schemas) for each handler. Provide unit tests for logic and integration tests for external bindings.
npm test
phantom test --integration
Export traces and metrics to your existing APM. Phantom ships with adapters for popular systems, but it also supports a generic HTTP exporter.
Official SDKs: JavaScript/TypeScript, Python, and Go. Community SDKs include Rust and Java. Language SDKs primarily expose the same event model and lifecycle hooks.
Use `phantom deploy` with a target environment. The CLI packages your handlers, uploads artifacts to a secure registry, and updates control-plane configuration.
Below are 10 colorful quick links to "Office" (for templates, team docs, and productivity tools). Each button is styled with a different gradient to be visually distinct — click any to open the Office portal (or change to your organization's URL).
Note: Replace the href
attributes with your internal Office/SharePoint URLs if you want these to point to company-specific resources.
import { Handler } from 'phantom-sdk';
export const handler: Handler = async (event, ctx) => {
try {
const data = JSON.parse(event.body || '{}');
// Validate payload...
return {
statusCode: 200,
body: JSON.stringify({ ok: true, received: data })
};
} catch (err) {
return { statusCode: 400, body: JSON.stringify({ error: 'invalid_payload' }) };
}
};
phantom new # scaffold a project
phantom dev # run locally
phantom build # build artifacts
phantom deploy --env=prod # deploy to production
phantom secrets set NAME --value=… # manage secrets
phantom logs --handler=hello # tail logs for a handler
from phantom import Client
client = Client(api_key="PHANTOM_API_KEY")
response = client.invoke('hello', payload={'name': 'alice'})
print(response.json())
def handle(event):
id = event.get('id')
if dedupe_store.exists(id):
return {'status': 200, 'body': 'already_processed'}
dedupe_store.put(id, True, ttl=3600)
# process event
return {'status': 200}