Build Nebius cloud infrastructure as typed Effect programs. GPU compute, VPC networks, IAM, object storage, DNS, KMS, and secrets — all in one TypeScript program, deployed with Alchemy.
Check the examples.
You need a Nebius account and Bun.
No external CLI required.
mkdir my-app && cd my-app && bun init -y
bun add alchemy@next effect@4.0.0-beta.103 @effect/platform-bun@4.0.0-beta.103 @effect/platform-node@4.0.0-beta.103 @fllstck/nebius-alchemy
Effect version is pinned to
4.0.0-beta.103—effect@beta(104+) renamesSchema.TaggedErrorClass, which alchemy 2.0.0-beta.70 still uses internally. Bump this pin when a new alchemy release supports the newer betas.Type checking with
tsc? This package ships raw TypeScript (bun-first, no build step). If you typecheck withtsc, enableallowImportingTsExtensions(requiresnoEmit), e.g."moduleResolution": "bundler", "allowImportingTsExtensions": true, "noEmit": true.
A simple stack that creates a Nebius Bucket.
// alchemy.run.ts
import * as Alchemy from 'alchemy'
import * as Effect from 'effect/Effect'
import * as Nebius from '@fllstck/nebius-alchemy'
export default Alchemy.Stack(
'Storage',
{
providers: Nebius.providers(),
state: Alchemy.localState(),
},
Effect.gen(function* () {
const bucket = yield* Nebius.storage.Bucket('MyBucket')
return { bucketId: bucket.id, bucketName: bucket.name }
}),
)
bun alchemy login
This opens your browser for a Nebius OAuth login, then asks you to pick a project — no external CLI, no API key, no environment variables. The chosen tenant and project are stored and used by every deploy.
Alternatively, for automation/CI:
sa-key — a service-account key (RSA-4096 authorized key). Renewal is
automatic via the RFC 8693 token exchange, so it needs no browser after the
one-time bootstrap (alchemy login → Service Account Key). In CI, set
NEBIUS_SA_ID, NEBIUS_SA_KEY_ID and NEBIUS_SA_PRIVATE_KEY.env — a static IAM API key via NEBIUS_API_KEY.Deploy the bucket.
bun alchemy deploy --yes
Delete the bucket.
bun alchemy destroy --yes
The package ships raw TypeScript source and requires these peer dependencies installed in your project:
| Package | Required | Notes |
|---|---|---|
effect | Yes | Effect V4 runtime (>=4.0.0-beta.102 or >=4.0.0) |
@effect/platform-bun | Yes | Bun platform bindings |
@effect/platform-node | Yes | Required by Alchemy CLI |
typescript | Yes | TypeScript 7 (^7.0.0) |
alchemy | Yes | Alchemy V2 (@next tag) |
The package uses .ts extensions in imports, so your tsconfig.json must enable bundler-style module resolution:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"strict": true,
"target": "ESNext"
}
}
The package uses Bun-native APIs and requires Bun >= 1.2.0 or Node >= 22.0.0.
| Variable | Required | Description |
| NEBIUS_PROJECT_ID | with env / env-var sa-key | Project ID — not needed after alchemy login or the SA bootstrap (picked at login) |
| NEBIUS_TENANT_ID | with env / env-var sa-key | Tenant ID for project/group discovery/creation actions |
| NEBIUS_API_KEY | with env | IAM API key for the env auth method |
| NEBIUS_SA_ID / NEBIUS_SA_KEY_ID / NEBIUS_SA_PRIVATE_KEY | with sa-key in CI | Service-account key material (RFC 8693 exchange) |
| NEBIUS_REGION | — | Default region (defaults to eu-north1) |
All resources that currently are currently implemented.
All resources use the NEBIUS_PROJECT_ID environment variable as default parentId where appropriate.
Deploy GPU-accelerated instances, disks, and managed filesystems.
Nebius.compute.Instance — GPU VMs with H200 support, preemptible instances, custom boot disks and network interfacesNebius.compute.Disk — Network SSD and HDD disks, bootable from images or snapshotsNebius.compute.Image — Dynamic image lookup by family (ubuntu-22-04-lts, etc.)Nebius.compute.Filesystem — Managed NFS filesystemsNebius.compute.DiskSnapshot — Point-in-time disk snapshotsRun containerized AI workloads on Nebius AI Cloud. Neither resource supports in-place updates — any spec change (or name change) replaces the resource.
Nebius.ai.Job — Run-to-completion container workloads (one run per resource; replace to re-run). Supports private registries, MysteryBox secret injection, injected config files, S3 volume mounts, and SSH accessNebius.ai.Endpoint — Long-running inference endpoints with public/private addresses, optional auth token (inline or MysteryBox secret), and start/stop lifecycleBuild complete software-defined network topologies.
Nebius.vpc.Network — Software-defined networks with auto-generated default route tablesNebius.vpc.Subnet — Subnets with zone assignment and CIDR blocksNebius.vpc.SecurityGroup — Firewall groupsNebius.vpc.SecurityRule — Stateful or stateless ingress/egress rules with protocol and port rangesNebius.vpc.RouteTable — Custom route tablesNebius.vpc.Route — Static routes with CIDR destinations and next-hop gatewaysNebius.vpc.Pool — IP address pools (IPv4, public or private)Nebius.vpc.Allocation — Individual IP allocations from a poolManage projects, service accounts, access keys, federation, groups, and permissions.
Nebius.iam.Project — Tenant projectsNebius.iam.ServiceAccount — Machine identities for programmatic accessNebius.iam.StaticKey — Long-lived static credentials (token only at creation time)Nebius.iam.AccessKey — S3-compatible access keys (v2 API with MysteryBox delivery)Nebius.iam.Federation — SAML/OIDC identity federationNebius.iam.FederationCertificate — X.509 certificates for federationsNebius.iam.Group — Access groupsNebius.iam.GroupMembership — Group member assignmentsNebius.iam.AccessPermit — Resource-level role grants (group-scoped)Nebius.iam.Invitation — User invitations with resend supportNebius.iam.AuthPublicKey — SSH public keys for authenticationNebius.iam.FederatedCredentials — Federated credential bindingsNebius.storage.Bucket — S3-compatible object storage bucketsNebius.storage.Transfer — Data transfer operations with iteration historyNebius.dns.Zone — VPC-scoped DNS zones with custom domainsNebius.dns.Record — A, AAAA, CNAME, TXT, MX, and other record typesNebius.kms.SymmetricKey — AES-256 encryption keysNebius.kms.AsymmetricKey — ECDSA and RSA signing/encryption keysNebius.mysterybox.Secret — Versioned secret storage with KMS encryption and inline payloadsNebius.mysterybox.SecretVersion — Secret versions with primary-version promotionNebius.quotas.QuotaAllowance — Project quota management by regionAlchemy actions for discovering existing resources without adopting them. Useful in alchemy plan for auditing.
Nebius.iam.action.ListProjects / GetProjectNebius.iam.action.ListGroups / GetGroupNebius.vpc.action.ListNetworks / GetNetworkNebius.vpc.action.ListSubnets / GetSubnetNebius.vpc.action.ListRouteTables / GetRouteTableNebius.quotas.action.ListQuotas / GetQuotaBindings are typed runtime clients you attach to your own Cloudflare Worker — no Nebius Function host required. One declaration derives three things at deploy time:
editors group + a region-scoped access key),plain_text/secret_text bindings,// api.ts
import * as Cloudflare from 'alchemy/Cloudflare'
import * as Effect from 'effect/Effect'
import * as Layer from 'effect/Layer'
import { NebiusBucket } from '@fllstck/nebius-alchemy/resources/storage/v1/bucket.ts'
import * as StorageBindings from '@fllstck/nebius-alchemy/resources/storage/v1/bindings.ts'
export const Api = Cloudflare.Worker(
'Api',
{ main: import.meta.url },
Effect.gen(function* () {
const bucket = yield* NebiusBucket('assets')
const getObject = yield* StorageBindings.GetObject(bucket)
const putObject = yield* StorageBindings.PutObject(bucket)
return {
fetch: /*...*/,
}
}).pipe(Effect.provide(Layer.mergeAll(StorageBindings.GetObjectHttp, StorageBindings.PutObjectHttp))),
)
Currently available (Cloudflare Workers):
| Contract | Layer | Runtime |
|---|---|---|
Nebius.storage.GetObject | Nebius.storage.GetObjectHttp | s3-lite-client (GET object) |
Nebius.storage.PutObject | Nebius.storage.PutObjectHttp | s3-lite-client (PUT object) |
Nebius.ai.ChatCompletions | Nebius.ai.ChatCompletionsHttp | fetch OpenAI-compatible POST /v1/chat/completions |
Nebius.ai.ChatCompletions(endpoint) derives the endpoint's public URL and
bearer token at deploy time and gives the Worker a typed, fetch-based
OpenAI-compatible client (ChatCompletionRequest → ChatCompletion, or an
SSE stream of ChatCompletionChunks with stream: true). The token deploys
as a Cloudflare secret_text binding; auth is a bearer token, so — unlike
the S3 bindings — there is no identity minting or IAM grant. The deploy
fails fast with EndpointNotRunning when the endpoint has no public endpoint
yet (it must be RUNNING). See AI_BINDINGS.md for the design
and examples/ai.bindings.ts for a full example.
Injected into the Worker at deploy time (names are stable):
| Env var | Meaning |
|---|---|
NEBIUS_S3_ENDPOINT | https://storage.<region>.nebius.cloud |
NEBIUS_REGION | Region the access key was minted in |
NEBIUS_ACCESS_KEY_ID | AWS-style access key id (plain text) |
NEBIUS_SECRET_ACCESS_KEY | Secret access key (deployed as secret_text) |
NEBIUS_BUCKET_NAME | The bound bucket's name |
NEBIUS_ENDPOINT_URL | The endpoint's first public URL (AI bindings) |
NEBIUS_ENDPOINT_AUTH_TOKEN | The endpoint's bearer token (secret_text; '' when auth disabled) |
See examples/storage.bindings.ts for the full pattern.
Small-bundle variant: the Effect-native worker bundles alchemy's runtime. If bundle size matters more than the typed contracts, use
examples/storage-async.bindings.ts.
| Example | What it demonstrates |
|---|---|
examples/storage.ts | Minimal bucket — the simplest possible stack |
examples/vpc.ts | Full VPC topology: network, subnet, routes, security group, IPAM |
examples/compute.ts | GPU instance: dynamic image lookup → disk → preemptible H200 instance |
examples/iam.ts | Service account with static key |
examples/dns.ts | VPC-scoped DNS zone with A record |
examples/kms.ts | Symmetric and asymmetric encryption keys |
examples/mysterybox.ts | Versioned secret with payload rotation |
examples/actions.ts | Read-only discovery actions for IAM, VPC, and quotas |
examples/storage.bindings.ts | Nebius S3 bindings for a Cloudflare Worker (Get/Put object) |
examples/ai.bindings.ts | Nebius AI endpoint bindings for a Cloudflare Worker (ChatCompletions) |
# Preview changes
bun alchemy plan
# Deploy
bun alchemy deploy
# Tear down
bun alchemy destroy
# Clear all
bun alchemy unsafe nuke
Resources follow the namespace hierarchy Nebius.<service>.<Resource>:
const bucket = yield* Nebius.storage.Bucket('MyBucket')
const network = yield* Nebius.vpc.Network('MyNetwork')
const instance = yield* Nebius.compute.Instance('MyInstance', { ... })
Names are auto-generated from logical IDs when omitted.
bun run check # typecheck + lint
bun test # unit tests only — network-free (see below)
bun run test:integration # SLOW_TESTS=1 bun test tests/ — everything
bun run generate:schemas # regenerate protobuf schemas from .proto files
SLOW_TESTS flagA plain bun test (no env vars) is guaranteed network-free: every test that deploys/destroys real Nebius resources or opens a real gRPC channel is gated behind the SLOW_TESTS flag and is reported as skip.
bun test # unit tests only — zero network I/O
SLOW_TESTS=1 bun test tests/ # full suite incl. real resource lifecycles
bun run test:integration # shorthand for the above
The flag lives in a single place —
tests/helpers/gate.ts(runIntegration()/integrationTest()). Integration tests additionally require real Nebius credentials (env/stored/CLI); api-client tests skip when credentials aren't resolvable. Destroy cleanup usessafeDestroy()fromtests/helpers/cleanup.ts— a failed destroy fails the test when the body succeeded, and logs (redacted) without masking the body's own failure otherwise.
Built on Effect V4 and Alchemy V2 with typed gRPC/protobuf clients for every Nebius API service. The provider uses Alchemy's resource lifecycle (reconcile, delete, diff, read) with factory helpers for standard CRUD operations. Protobuf schemas live under schemas/ and are generated from the Nebius API .proto files via buf generate.
134 commits
TypeScript
99.7%
Build Nebius cloud infrastructure as typed Effect programs. GPU compute, VPC networks, IAM, object storage, DNS, KMS, and secrets — all in one TypeScript program, deployed with Alchemy.
Check the examples.
You need a Nebius account and Bun.
No external CLI required.
mkdir my-app && cd my-app && bun init -y
bun add alchemy@next effect@4.0.0-beta.103 @effect/platform-bun@4.0.0-beta.103 @effect/platform-node@4.0.0-beta.103 @fllstck/nebius-alchemy
Effect version is pinned to
4.0.0-beta.103—effect@beta(104+) renamesSchema.TaggedErrorClass, which alchemy 2.0.0-beta.70 still uses internally. Bump this pin when a new alchemy release supports the newer betas.Type checking with
tsc? This package ships raw TypeScript (bun-first, no build step). If you typecheck withtsc, enableallowImportingTsExtensions(requiresnoEmit), e.g."moduleResolution": "bundler", "allowImportingTsExtensions": true, "noEmit": true.
A simple stack that creates a Nebius Bucket.
// alchemy.run.ts
import * as Alchemy from 'alchemy'
import * as Effect from 'effect/Effect'
import * as Nebius from '@fllstck/nebius-alchemy'
export default Alchemy.Stack(
'Storage',
{
providers: Nebius.providers(),
state: Alchemy.localState(),
},
Effect.gen(function* () {
const bucket = yield* Nebius.storage.Bucket('MyBucket')
return { bucketId: bucket.id, bucketName: bucket.name }
}),
)
bun alchemy login
This opens your browser for a Nebius OAuth login, then asks you to pick a project — no external CLI, no API key, no environment variables. The chosen tenant and project are stored and used by every deploy.
Alternatively, for automation/CI:
sa-key — a service-account key (RSA-4096 authorized key). Renewal is
automatic via the RFC 8693 token exchange, so it needs no browser after the
one-time bootstrap (alchemy login → Service Account Key). In CI, set
NEBIUS_SA_ID, NEBIUS_SA_KEY_ID and NEBIUS_SA_PRIVATE_KEY.env — a static IAM API key via NEBIUS_API_KEY.Deploy the bucket.
bun alchemy deploy --yes
Delete the bucket.
bun alchemy destroy --yes
The package ships raw TypeScript source and requires these peer dependencies installed in your project:
| Package | Required | Notes |
|---|---|---|
effect | Yes | Effect V4 runtime (>=4.0.0-beta.102 or >=4.0.0) |
@effect/platform-bun | Yes | Bun platform bindings |
@effect/platform-node | Yes | Required by Alchemy CLI |
typescript | Yes | TypeScript 7 (^7.0.0) |
alchemy | Yes | Alchemy V2 (@next tag) |
The package uses .ts extensions in imports, so your tsconfig.json must enable bundler-style module resolution:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"strict": true,
"target": "ESNext"
}
}
The package uses Bun-native APIs and requires Bun >= 1.2.0 or Node >= 22.0.0.
| Variable | Required | Description |
| NEBIUS_PROJECT_ID | with env / env-var sa-key | Project ID — not needed after alchemy login or the SA bootstrap (picked at login) |
| NEBIUS_TENANT_ID | with env / env-var sa-key | Tenant ID for project/group discovery/creation actions |
| NEBIUS_API_KEY | with env | IAM API key for the env auth method |
| NEBIUS_SA_ID / NEBIUS_SA_KEY_ID / NEBIUS_SA_PRIVATE_KEY | with sa-key in CI | Service-account key material (RFC 8693 exchange) |
| NEBIUS_REGION | — | Default region (defaults to eu-north1) |
All resources that currently are currently implemented.
All resources use the NEBIUS_PROJECT_ID environment variable as default parentId where appropriate.
Deploy GPU-accelerated instances, disks, and managed filesystems.
Nebius.compute.Instance — GPU VMs with H200 support, preemptible instances, custom boot disks and network interfacesNebius.compute.Disk — Network SSD and HDD disks, bootable from images or snapshotsNebius.compute.Image — Dynamic image lookup by family (ubuntu-22-04-lts, etc.)Nebius.compute.Filesystem — Managed NFS filesystemsNebius.compute.DiskSnapshot — Point-in-time disk snapshotsRun containerized AI workloads on Nebius AI Cloud. Neither resource supports in-place updates — any spec change (or name change) replaces the resource.
Nebius.ai.Job — Run-to-completion container workloads (one run per resource; replace to re-run). Supports private registries, MysteryBox secret injection, injected config files, S3 volume mounts, and SSH accessNebius.ai.Endpoint — Long-running inference endpoints with public/private addresses, optional auth token (inline or MysteryBox secret), and start/stop lifecycleBuild complete software-defined network topologies.
Nebius.vpc.Network — Software-defined networks with auto-generated default route tablesNebius.vpc.Subnet — Subnets with zone assignment and CIDR blocksNebius.vpc.SecurityGroup — Firewall groupsNebius.vpc.SecurityRule — Stateful or stateless ingress/egress rules with protocol and port rangesNebius.vpc.RouteTable — Custom route tablesNebius.vpc.Route — Static routes with CIDR destinations and next-hop gatewaysNebius.vpc.Pool — IP address pools (IPv4, public or private)Nebius.vpc.Allocation — Individual IP allocations from a poolManage projects, service accounts, access keys, federation, groups, and permissions.
Nebius.iam.Project — Tenant projectsNebius.iam.ServiceAccount — Machine identities for programmatic accessNebius.iam.StaticKey — Long-lived static credentials (token only at creation time)Nebius.iam.AccessKey — S3-compatible access keys (v2 API with MysteryBox delivery)Nebius.iam.Federation — SAML/OIDC identity federationNebius.iam.FederationCertificate — X.509 certificates for federationsNebius.iam.Group — Access groupsNebius.iam.GroupMembership — Group member assignmentsNebius.iam.AccessPermit — Resource-level role grants (group-scoped)Nebius.iam.Invitation — User invitations with resend supportNebius.iam.AuthPublicKey — SSH public keys for authenticationNebius.iam.FederatedCredentials — Federated credential bindingsNebius.storage.Bucket — S3-compatible object storage bucketsNebius.storage.Transfer — Data transfer operations with iteration historyNebius.dns.Zone — VPC-scoped DNS zones with custom domainsNebius.dns.Record — A, AAAA, CNAME, TXT, MX, and other record typesNebius.kms.SymmetricKey — AES-256 encryption keysNebius.kms.AsymmetricKey — ECDSA and RSA signing/encryption keysNebius.mysterybox.Secret — Versioned secret storage with KMS encryption and inline payloadsNebius.mysterybox.SecretVersion — Secret versions with primary-version promotionNebius.quotas.QuotaAllowance — Project quota management by regionAlchemy actions for discovering existing resources without adopting them. Useful in alchemy plan for auditing.
Nebius.iam.action.ListProjects / GetProjectNebius.iam.action.ListGroups / GetGroupNebius.vpc.action.ListNetworks / GetNetworkNebius.vpc.action.ListSubnets / GetSubnetNebius.vpc.action.ListRouteTables / GetRouteTableNebius.quotas.action.ListQuotas / GetQuotaBindings are typed runtime clients you attach to your own Cloudflare Worker — no Nebius Function host required. One declaration derives three things at deploy time:
editors group + a region-scoped access key),plain_text/secret_text bindings,// api.ts
import * as Cloudflare from 'alchemy/Cloudflare'
import * as Effect from 'effect/Effect'
import * as Layer from 'effect/Layer'
import { NebiusBucket } from '@fllstck/nebius-alchemy/resources/storage/v1/bucket.ts'
import * as StorageBindings from '@fllstck/nebius-alchemy/resources/storage/v1/bindings.ts'
export const Api = Cloudflare.Worker(
'Api',
{ main: import.meta.url },
Effect.gen(function* () {
const bucket = yield* NebiusBucket('assets')
const getObject = yield* StorageBindings.GetObject(bucket)
const putObject = yield* StorageBindings.PutObject(bucket)
return {
fetch: /*...*/,
}
}).pipe(Effect.provide(Layer.mergeAll(StorageBindings.GetObjectHttp, StorageBindings.PutObjectHttp))),
)
Currently available (Cloudflare Workers):
| Contract | Layer | Runtime |
|---|---|---|
Nebius.storage.GetObject | Nebius.storage.GetObjectHttp | s3-lite-client (GET object) |
Nebius.storage.PutObject | Nebius.storage.PutObjectHttp | s3-lite-client (PUT object) |
Nebius.ai.ChatCompletions | Nebius.ai.ChatCompletionsHttp | fetch OpenAI-compatible POST /v1/chat/completions |
Nebius.ai.ChatCompletions(endpoint) derives the endpoint's public URL and
bearer token at deploy time and gives the Worker a typed, fetch-based
OpenAI-compatible client (ChatCompletionRequest → ChatCompletion, or an
SSE stream of ChatCompletionChunks with stream: true). The token deploys
as a Cloudflare secret_text binding; auth is a bearer token, so — unlike
the S3 bindings — there is no identity minting or IAM grant. The deploy
fails fast with EndpointNotRunning when the endpoint has no public endpoint
yet (it must be RUNNING). See AI_BINDINGS.md for the design
and examples/ai.bindings.ts for a full example.
Injected into the Worker at deploy time (names are stable):
| Env var | Meaning |
|---|---|
NEBIUS_S3_ENDPOINT | https://storage.<region>.nebius.cloud |
NEBIUS_REGION | Region the access key was minted in |
NEBIUS_ACCESS_KEY_ID | AWS-style access key id (plain text) |
NEBIUS_SECRET_ACCESS_KEY | Secret access key (deployed as secret_text) |
NEBIUS_BUCKET_NAME | The bound bucket's name |
NEBIUS_ENDPOINT_URL | The endpoint's first public URL (AI bindings) |
NEBIUS_ENDPOINT_AUTH_TOKEN | The endpoint's bearer token (secret_text; '' when auth disabled) |
See examples/storage.bindings.ts for the full pattern.
Small-bundle variant: the Effect-native worker bundles alchemy's runtime. If bundle size matters more than the typed contracts, use
examples/storage-async.bindings.ts.
| Example | What it demonstrates |
|---|---|
examples/storage.ts | Minimal bucket — the simplest possible stack |
examples/vpc.ts | Full VPC topology: network, subnet, routes, security group, IPAM |
examples/compute.ts | GPU instance: dynamic image lookup → disk → preemptible H200 instance |
examples/iam.ts | Service account with static key |
examples/dns.ts | VPC-scoped DNS zone with A record |
examples/kms.ts | Symmetric and asymmetric encryption keys |
examples/mysterybox.ts | Versioned secret with payload rotation |
examples/actions.ts | Read-only discovery actions for IAM, VPC, and quotas |
examples/storage.bindings.ts | Nebius S3 bindings for a Cloudflare Worker (Get/Put object) |
examples/ai.bindings.ts | Nebius AI endpoint bindings for a Cloudflare Worker (ChatCompletions) |
# Preview changes
bun alchemy plan
# Deploy
bun alchemy deploy
# Tear down
bun alchemy destroy
# Clear all
bun alchemy unsafe nuke
Resources follow the namespace hierarchy Nebius.<service>.<Resource>:
const bucket = yield* Nebius.storage.Bucket('MyBucket')
const network = yield* Nebius.vpc.Network('MyNetwork')
const instance = yield* Nebius.compute.Instance('MyInstance', { ... })
Names are auto-generated from logical IDs when omitted.
bun run check # typecheck + lint
bun test # unit tests only — network-free (see below)
bun run test:integration # SLOW_TESTS=1 bun test tests/ — everything
bun run generate:schemas # regenerate protobuf schemas from .proto files
SLOW_TESTS flagA plain bun test (no env vars) is guaranteed network-free: every test that deploys/destroys real Nebius resources or opens a real gRPC channel is gated behind the SLOW_TESTS flag and is reported as skip.
bun test # unit tests only — zero network I/O
SLOW_TESTS=1 bun test tests/ # full suite incl. real resource lifecycles
bun run test:integration # shorthand for the above
The flag lives in a single place —
tests/helpers/gate.ts(runIntegration()/integrationTest()). Integration tests additionally require real Nebius credentials (env/stored/CLI); api-client tests skip when credentials aren't resolvable. Destroy cleanup usessafeDestroy()fromtests/helpers/cleanup.ts— a failed destroy fails the test when the body succeeded, and logs (redacted) without masking the body's own failure otherwise.
Built on Effect V4 and Alchemy V2 with typed gRPC/protobuf clients for every Nebius API service. The provider uses Alchemy's resource lifecycle (reconcile, delete, diff, read) with factory helpers for standard CRUD operations. Protobuf schemas live under schemas/ and are generated from the Nebius API .proto files via buf generate.
134 commits
TypeScript
99.7%