Runtime contract and SDK
Supported application model
V1 supports:
Nuxt
↓
Nitro Workers-compatible output
↓
workerd
The platform does not support:
- Arbitrary Linux containers
- Express servers listening on a port
- Persistent Node processes
- Native Node add-ons
- Arbitrary binaries
- Local durable filesystem
- Raw TCP or UDP
- Dockerfiles
- User-managed daemons
- Background threads intended to live forever
Next.js is a later framework target using the same runtime contract.
Web-platform APIs
Supported APIs include the documented runtime subset of:
Request
Response
Headers
URL
URLPattern where supported
fetch
ReadableStream
WritableStream
TransformStream
WebSocket where supported
crypto
TextEncoder/TextDecoder
AbortController
console
timers within platform limits
Node compatibility is a documented subset—not a promise that the runtime behaves like a conventional Node server.
Runtime compatibility version
Each app pins a contract version:
export default defineIntrnlConfig({
compatibilityDate: '2026-09-01',
runtime: 'workers',
});
Platform upgrades preserve existing behavior where practical.
New APIs or breaking semantics require a new compatibility version and an explicit app upgrade.
workerd itself uses date-based compatibility behavior, which aligns well with this model. Workers compatibility dates
Bindings
V1 bindings:
DB
KV
AUTH
CONFIG
INTEGRATIONS
Potential later bindings:
FILES
QUEUE
SCHEDULE
SERVICE
AI
Cloudflare’s binding model is useful because a binding supplies both a capability and its API without revealing the underlying secret or connection material. Workers bindings
Database binding
D1-inspired API:
const result = await env.DB
.prepare('SELECT * FROM requests WHERE owner_id = ?')
.bind(user.id)
.all();
const record = await env.DB
.prepare('SELECT * FROM requests WHERE id = ?')
.bind(id)
.first();
await env.DB
.prepare('INSERT INTO requests (...) VALUES (...)')
.bind(...)
.run();
await env.DB.batch([
env.DB.prepare(...).bind(...),
env.DB.prepare(...).bind(...),
]);
This mirrors the familiar prepared-statement shape of D1’s Worker binding without promising complete D1 product parity. D1 prepared statements
Document intrnl’s own semantics for:
- Batch atomicity
- Result shapes
- Errors
- Parameter types
- Limits
- Concurrency
- Timeouts
- Schema operations
KV binding
await env.KV.get('key');
await env.KV.get('key', { type: 'json' });
await env.KV.put('key', value, { expirationTtl: 3600 });
await env.KV.delete('key');
await env.KV.list({ prefix: 'session:' });
Valkey may provide stronger consistency than Cloudflare KV. Do not artificially weaken it for compatibility.
The documented contract should state:
intrnl KV uses a Workers-style API but has intrnl-specific consistency and limits.
Authentication binding
const user = env.AUTH.user;
or:
const user = useIntrnlUser();
Fields:
id
organizationId
email
displayName
groups
platformRoles
identityProvider
The SDK distinguishes platform groups from app-owned business roles.
Configuration binding
Non-secret settings:
env.CONFIG.get('SUPPORT_EMAIL');
env.CONFIG.get('FEATURE_X_ENABLED');
These values may be visible to authorized creators and AI.
Secrets and integrations
Preferred proxy model (an enterprise resource planning integration is a future capability, excluded from v1):
App
↓ env.INTEGRATIONS.ERP.fetch(...)
Credential-injecting integration proxy
↓
Approved destination
The application does not see the raw credential.
For a generic external API:
await env.INTEGRATIONS.ACCOUNTING.fetch('/invoices', {
method: 'POST',
body: ...
});
The integration definition controls:
- Destination hostname
- Allowed path prefixes
- Allowed methods
- Authentication injection
- Request/response size
- Rate limit
- Logging/redaction
- Environment-specific credential
Raw secret bindings should exist only when a proxy cannot satisfy the use case. They require higher risk classification and explicit approval.
The AI may see the integration’s name and schema but never its plaintext credential.
Static assets
Build output is split into:
Worker bundle
Immutable hashed static assets
The gateway or static service answers asset requests without invoking the Worker when possible. This matches the general Workers model in which static assets can be deployed alongside Worker logic and served directly. Workers static assets
Runtime limits
Limits are configurable by plan/risk profile:
- Memory
- CPU time
- Wall-clock duration
- Request body size
- Response body size
- Concurrent requests
- Outbound subrequests
- Open connections
- DB statements
- KV operations
- Log volume
- Bundle size
- Static asset volume
Phase 0 benchmarks establish production defaults. A 128 MiB compatibility test profile is a reasonable starting point for Workers-like applications, but final intrnl limits should reflect actual Nuxt workloads rather than blindly copying another platform.
@intrnl/sdk and Nuxt module
Packages:
@intrnl/sdk
@intrnl/nuxt
Responsibilities:
- Typed binding interfaces
- User/session access
- Error normalization
- Local development adapters
- Test fakes
- Runtime contract validation
- Database and KV helpers
- Integration clients
- Audit/correlation context
- Nuxt composables and server middleware
The SDK is convenience, not the security boundary.
Configuration file
// intrnl.config.ts
export default defineIntrnlConfig({
framework: 'nuxt',
runtime: 'workers',
compatibilityDate: '2026-09-01',
bindings: {
DB: { type: 'sqlite' },
KV: { type: 'kv' },
},
capabilities: {
outboundHttp: [],
integrations: [],
},
});
The console and AI manage this for nontechnical users. Developers may edit it directly.
Contract details still to validate
The method names above are proposed interface shapes. Phase 0 must establish DB batch atomicity, result/error types, supported parameters, timeouts, statement limits, WAL/concurrency behavior, and multiple-replica behavior. It must also establish KV consistency, size and TTL limits, list pagination, and recovery behavior. Until those results are accepted, do not infer Cloudflare D1 or KV parity.
The sample 2026-09-01 compatibility date illustrates version pinning. It does not name an available intrnl release. The 128 MiB profile is a benchmark input, not a promised production limit.