Getting started
Try a small storage example, then choose the package and framework guide for your application.
You can adopt one Playstack package without replacing your framework or adopting the whole stack. All @playstack/* packages share one release version, regardless of access tier. Keep them on the same version in your application.
Requirements
- Node.js 22 or newer for new server projects.
- TypeScript with modern ESM and package exports support.
- A terminal and an existing Node project, or an empty directory where you can run
npm init -y.
Install only what you use
First check preview access. These examples assume your chosen version is available from your approved package source. For account-free public releases, use npm's default registry. If you have private registry access, add these lines to your project's .npmrc:
# .npmrc — the token comes from your environment
@playstack:registry=https://registry.playstack.dev/
//registry.playstack.dev/:_authToken=${PLAYSTACK_REGISTRY_TOKEN}The URL and literal ${PLAYSTACK_REGISTRY_TOKEN} placeholder can be committed. The real token must stay in your shell environment or CI secret store, never in Git. Set it using your approved secret manager before installing.
Run the install command separately in your terminal:
npm install --save-exact @playstack/storage@0.1.0-beta.1The scope setting sends all @playstack/* requests to that registry, including Free packages. npm does not automatically fall back to public npm for a missing package. Confirm the selected release and its dependencies are available there.
Your first working example
Save this as quickstart.mjs. It writes and reads a text file using an in-memory provider, so you do not need a database, cloud account or storage credentials. The same API can later use a real storage provider.
import { createStorage } from '@playstack/storage'
import { MemoryStorageProvider } from '@playstack/storage/testing'
const storage = createStorage({
driver: new MemoryStorageProvider(),
prefix: 'quickstart',
})
await storage.put('hello.txt', 'Hello, Playstack!', {
contentType: 'text/plain',
})
const object = await storage.get('hello.txt')
if (!object) throw new Error('Expected the object we just saved')
console.log(await new Response(object.body).text())
console.log(await storage.exists('hello.txt'))Run it:
node quickstart.mjsExpected output:
Hello, Playstack!
trueYou have now used a Playstack capability without adopting a framework or another service. createStorage owns the common API; the provider owns where bytes live. The memory provider is for learning and tests only: its contents disappear when the process exits. For durable storage, follow the Storage guide and choose a filesystem, S3 or Workers R2 provider.
Choose your next step
- Find another capability: browse Packages by the problem you want to solve.
- Use an existing framework: follow the Next.js, React, NestJS or Workers integration guide. These assume an existing app and call out the services you must supply.
- Look up an API: open a package page for its examples and options, then use the installed TypeScript declarations for exact signatures. Reading the package reference explains the distinction.
Add framework adapters only where they help. A Next application can use storage directly on the server; a Nest application can optionally register it through a module.
If Megamono owns your workspace structure, follow Using Playstack with Megamono for the handoff between app and database scaffolding, capability installation, schema compatibility, and application-owned migrations.
When you add commands and events
You do not need operation context for the example above. When a capability produces events, context helps connect them to the request or job that caused them.
Create context once at the outside boundary and pass it into commands that produce events:
import type { OperationContext } from '@playstack/core'
export function contextFromRequest(requestId: string): OperationContext {
return {
correlationId: requestId,
trace: { traceId: requestId },
}
}When one event causes another command, pass the source envelope as the cause. Playstack adapters preserve that relationship when they bridge domain events into the application event system.
Moving from the example to an application
Create infrastructure clients in one application setup module (often called the composition root) and pass them into the packages that need them. That gives your application control over credentials, shutdown, access checks and tests without changing the domain API. Before production, read the chosen provider's limits and test failures against your real infrastructure.
Follow package progress
Use the status inventory for current package and adapter coverage, the changelog for release notes, and pricing for package access.