npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fractal_cloud/sdk

v2.3.2

Published

Typescript Fractal Cloud SDK

Readme

Fractal Cloud TypeScript SDK

NPM Version build status codecov license Known Vulnerabilities TypeScript Style Guide

Overview

The Fractal Cloud TypeScript SDK lets platform engineers and application developers define cloud-agnostic infrastructure blueprints in TypeScript and deploy them to any supported cloud provider.

Infrastructure is modelled as reusable architectural building blocks — Fractals — that can be validated, governed, and evolved over time. A Live System is produced by selecting, per component, a concrete Offer from the catalogue — without ever touching vendor-specific tooling or DSLs.

Why Fractal

Traditional Infrastructure as Code forces a choice between flexibility and control:

  • Tightly coupled to a specific cloud vendor
  • String-heavy DSLs with no type safety
  • Hard to govern at scale
  • Focused on raw resources rather than architecture

Fractal Cloud takes a different approach: define infrastructure as architecture, stay cloud-agnostic by design, and let the Fractal Automation Engine handle provisioning and drift reconciliation.

Core concepts

Fractal (Blueprint)

A Fractal is a governed, reusable infrastructure pattern. It references abstract Components only — never offers or vendors — and declares their structure (dependencies and links) and their guardrails (locked parameters). Adding a vendor never requires editing an existing Fractal.

Live System

A Live System is a running instance of a Fractal. It is built by per-component offer selection: each abstract Component is mapped to one concrete provider-specific Offer that carries the vendor parameters the Automation Engine needs. There is no global provider — mixed-vendor live systems are normal. There are no state files; the cloud is the source of truth.

The Catalogue — three levels

Level 1 — COMPONENT   {domain}.{name}                  e.g. Storage.ObjectStorage
                      Abstract capability contract. Referenced by blueprints. Never provisioned.

Level 2 — SERVICE     {domain}.{deliveryModel}.{name}   delivery-model contract. Never provisioned.

Level 3 — OFFER       {domain}.{deliveryModel}.{name} + a provider
                      Concrete, vendor-specific. The only level that maps to real infra.

A blueprint references a Component (Storage.ObjectStorage); a Live System selects any Offer that satisfies it (AwsS3, AzureBlob, GcsBucket, MinIO, …). Selection is compile-checked: an offer that does not satisfy a slot's Component is a type error (and is also rejected at runtime).

provider is a vendor axis (AWS | Azure | GCP | OCI | Hetzner | Aruba | RedHat | VMware). IaaS | PaaS | CaaS | SaaS | FaaS is the separate deliveryModel axis. Vendor-neutral self-hosted offers (e.g. Kafka, Prometheus, MinIO on any cluster) omit provider.

Guardrails vs operations

| Surface | Who sets it | When | Effect | |---|---|---|---| | Guardrail.withXxx() on a Component, at design time | The architect, inside createFractal | Authoring | Sets a neutral parameter and locks it. Devs cannot override; a later write throws. | | Operation — a verb on the Fractal operations interface | The consuming dev, via .specialize() | Specialization | Application-level intent (withCollation, withDatabases, withRoutes). Writes open params or adds child components. Never a pass-through infra knob. | | Vendor config — an Offer's config object | The dev, at offer selection | Live System | Vendor-only knobs (bucketRegion, amiId, resourceGroup, …). |

Installation

npm install @fractal_cloud/sdk

Package page · Source repository

Requires Node.js 18+ and TypeScript 5+.

Quick start

The following defines a cloud-agnostic blueprint (a VPC, a subnet, a security group, two VMs, and a container platform), then specializes it and selects AWS offers to build and deploy a Live System.

1. Author the Fractal (fractal.ts)

import {
  createFractal,
  VirtualNetwork, Subnet, SecurityGroup, VirtualMachine, ContainerPlatform,
} from '@fractal_cloud/sdk';

const boundedContextId = {
  ownerType: 'Personal',
  ownerId: process.env['OWNER_ID']!,
  name: 'my-team',
};

export const fractal = createFractal({
  id: 'standard-network',
  version: {major: 1, minor: 0, patch: 0},
  boundedContextId,
  blueprint: bp => {
    const network = bp.add(
      VirtualNetwork({id: 'main-network'})
        .withCidrBlock('10.0.0.0/16')
        .withRegion('us-east-1'),
    );
    const subnet = bp.add(
      Subnet({id: 'app-subnet'}).withCidrBlock('10.0.1.0/24').dependsOn(network),
    );
    const sg = bp.add(
      SecurityGroup({id: 'app-sg'})
        .withIngressRules([{protocol: 'tcp', fromPort: 443, sourceCidr: '0.0.0.0/0'}])
        .dependsOn(network),
    );
    const web = bp.add(VirtualMachine({id: 'web-server'}).withOsType('linux').dependsOn(subnet));
    const api = bp.add(VirtualMachine({id: 'api-server'}).withOsType('linux').dependsOn(subnet));
    const cluster = bp.add(
      ContainerPlatform({id: 'app-cluster'}).withKubernetesVersion('1.29').dependsOn(subnet),
    );

    // Runtime link: web can reach api on 8080 (blueprint owns all links).
    bp.link(web, api, {fromPort: 8080, protocol: 'tcp'});

    return {network, subnet, sg, web, api, cluster};
  },
});

2. Select offers and build the Live System (aws_live_system.ts)

import {
  AwsVpc, AwsSubnet, AwsSecurityGroup, Ec2Instance, Eks,
} from '@fractal_cloud/sdk';
import {fractal} from './fractal';

const environment = {
  ownerType: 'Personal',
  ownerId: process.env['OWNER_ID']!,
  name: 'dev',
};

export const liveSystem = fractal.specialize().toLiveSystem({
  name: 'acme-net-aws',
  environment,
  select: {
    'main-network': AwsVpc({}),
    'app-subnet':   AwsSubnet({}),
    'app-sg':       AwsSecurityGroup({}),
    'web-server':   Ec2Instance({amiId: 'ami-0c55b159cbfafe1f0', instanceType: 't3.micro'}),
    'api-server':   Ec2Instance({amiId: 'ami-0c55b159cbfafe1f0', instanceType: 't3.small'}),
    'app-cluster':  Eks({}),
  },
});

Every component id must map to an offer whose satisfies matches its Component. Selecting, say, AwsVpc({}) for 'app-subnet' is a compile-time error.

3. Deploy (index.ts)

import {deploy} from '@fractal_cloud/sdk';
import {liveSystem} from './aws_live_system';

const credentials = {
  clientId: process.env['SERVICE_ACCOUNT_ID']!,
  clientSecret: process.env['SERVICE_ACCOUNT_SECRET']!,
};

await deploy(liveSystem, credentials, {mode: 'wait'});

deploy submits the Live System (create or update) to Fractal Cloud; the Automation Engine reconciles cloud resources to match it.

Deployment modes

deploy(liveSystem, credentials, options) supports two modes.

Fire and forget (default)

Submits the live system and returns immediately. Provisioning happens asynchronously. This is the default when no options are passed.

await deploy(liveSystem, credentials);
await deploy(liveSystem, credentials, {mode: 'fire-and-forget'}); // equivalent

Best for: applications, CLIs, scripts where infrastructure deployment is a background concern.

Wait for Active

Submits, then polls until the live system reaches Active. Throws on terminal failure (FailedMutation, Error) or timeout.

await deploy(liveSystem, credentials, {
  mode: 'wait',
  pollIntervalMs: 10_000, // check every 10 s  (default: 5 s)
  timeoutMs: 900_000,     // give up after 15 min (default: 10 min)
  quiet: false,           // set true to suppress wait-mode log lines
});
// reaches here only when the live system is fully Active

Best for: CI/CD pipelines that must not advance until infrastructure is provisioned.

Destroy

import {destroy} from '@fractal_cloud/sdk';
await destroy(liveSystem, credentials);

Catalogue

The blueprint references the Component in the left column; a Live System selects any Offer beneath it. Offers with no provider are vendor-neutral self-hosted (run on any cluster).

NetworkAndCompute

| Component | AWS | Azure | GCP | OCI | Hetzner | VMware | RedHat (OpenShift) | |---|---|---|---|---|---|---|---| | VirtualNetwork | AwsVpc | AzureVnet | GcpVpc | OciVcn | HetznerNetwork | VspherePortGroup | — | | Subnet | AwsSubnet | AzureSubnet | GcpSubnet | OciSubnet | HetznerSubnet | VsphereVlan | — | | SecurityGroup | AwsSecurityGroup | AzureNsg | GcpFirewall | OciSecurityList | HetznerFirewall | — | OpenshiftSecurityGroup | | VirtualMachine | Ec2Instance | AzureVm | GcpVm | OciInstance | HetznerServer | VsphereVm | OpenshiftVm | | ContainerPlatform | Eks | Aks | Gke | — | — | — | — | | LoadBalancer | AwsLb | AzureLb | GcpGlb | — | — | — | OpenshiftService |

CustomWorkloads

| Component | AWS | Azure | GCP | RedHat | Self-hosted | |---|---|---|---|---|---| | Workload | EcsService | AzureContainerApp | CloudRun | OpenshiftWorkload | K8sWorkload | | Function | AwsLambda | AzureFunction | GcpFunction | — | — |

Storage

| Component | AWS | Azure | GCP | Aruba | RedHat | Self-hosted | |---|---|---|---|---|---|---| | ObjectStorage | AwsS3 | AzureBlob | GcsBucket | — | OpenshiftPersistentVolume | MinIO | | RelationalDbms | — | AzurePostgresDbms | GcpPostgresDbms | ArubaMySqlDbms | — | — | | RelationalDatabase | — | AzurePostgresDatabase | GcpPostgresDatabase | — | — | — |

RelationalDatabase components added under a DBMS via an operation are emitted by the DBMS's own offer in its vendor family — selecting AzurePostgresDbms makes its databases AzurePostgresDatabase. They are not independently offer-selected.

Messaging

| Component | Azure | GCP | Self-hosted | |---|---|---|---| | Broker | AzureServiceBus | GcpPubSub | Kafka | | MessagingEntity | AzureServiceBusTopic | GcpPubSubTopic | KafkaTopic |

BigData

| Component | AWS | Azure | GCP | Self-hosted | |---|---|---|---|---| | DistributedDataProcessing | AwsDatabricks | AzureDatabricks | GcpDatabricks | — | | ComputeCluster | AwsDatabricksCluster | AzureDatabricksCluster | GcpDatabricksCluster | CaaSSparkCluster | | DataProcessingJob | AwsDatabricksJob | AzureDatabricksJob | GcpDatabricksJob | CaaSSparkJob | | MlExperiment | AwsDatabricksMlflow | AzureDatabricksMlflow | GcpDatabricksMlflow | CaaSMlflow | | Datalake | AwsS3Datalake | AzureDatalake | GcpDatalake | — |

APIManagement

| Component | AWS | Azure | GCP | Self-hosted | |---|---|---|---|---| | ApiGateway | AwsCloudFront | AzureApiManagement | GcpApiGateway | Ambassador · Traefik |

Observability (self-hosted, CaaS)

| Component | Offer | |---|---| | Monitoring | Prometheus | | Tracing | Jaeger | | Logging | ObservabilityElastic |

Security

| Component | AWS | Self-hosted | |---|---|---| | ServiceMesh | — | Ocelot | | IdentityProvider | Cognito | Keycloak |

Extending the catalogue

Both Components and Offers are plain values — you can add your own without forking.

Add a new Offer (including a new vendor)

defineOffer returns an offer constructor. Declare which Component it satisfies, its 3-part offerType, its deliveryModel, an optional provider (one of the Provider vendors; omit for vendor-neutral self-hosted), and a config type for vendor knobs. Every existing Fractal can select it automatically — no blueprint changes.

import {defineOffer} from '@fractal_cloud/sdk';

// A self-hosted object store satisfying the built-in Storage.ObjectStorage
// Component. Vendor-neutral, so `provider` is omitted.
const Ceph = defineOffer<'Storage.ObjectStorage', {storageClass?: string}>({
  satisfies: 'Storage.ObjectStorage',
  offerType: 'Storage.CaaS.Ceph',
  deliveryModel: 'CaaS',
});

// Select it for any ObjectStorage slot, just like a built-in offer:
fractal.specialize().toLiveSystem({
  name: 'acme-prod',
  environment,
  select: {uploads: Ceph({storageClass: 'rbd'})},
});

By default an offer emits one live component merging the blueprint's neutral params with its vendor config. Pass an instantiate(ctx, config) to emit a custom set of live components (e.g. a parent plus one child per ctx.children entry).

Add a new abstract Component

Author a Component factory on the core authoring primitives (newNode, guardrail, addDependency). Each .withXxx() setter records a neutral parameter and locks it as a guardrail.

import {ComponentNode, NodeState, newNode, guardrail} from '@fractal_cloud/sdk';

type TimeSeriesNode<Id extends string = string> = ComponentNode<Id, 'Analytics.TimeSeries'> & {
  withRetentionDays: (v: number) => TimeSeriesNode<Id>;
};
const node = <Id extends string>(s: NodeState): TimeSeriesNode<Id> => ({
  state: s,
  withRetentionDays: v => node<Id>(guardrail(s, 'retentionDays', v)),
});
export const TimeSeries = <const Id extends string>(cfg: {id: Id}): TimeSeriesNode<Id> =>
  node<Id>(newNode(cfg.id, 'Analytics.TimeSeries'));

Then write offers that satisfies: 'Analytics.TimeSeries'. Custom domains, components, and vendors must be registered with the Fractal Cloud platform for deployment to succeed.

Samples

The sample repository contains ready-to-run examples consumed via the @fractal_cloud/sdk/model subpath. basic_storage is the canonical reference.

Architecture

The package root and the ./model subpath export the same surface.

src/model/
  core.ts          # Engine: createFractal, defineOffer, ComponentNode, typed Selection,
                   #         guardrails/locking, links, child components, fluent .specialize()
  service.ts       # deploy / destroy a LiveSystem (HTTP + poll + wait-mode log contract)
  index.ts         # Public barrel
  components/      # Abstract Component factories (Level 1, vendor-agnostic)
    network_and_compute.ts   # VirtualNetwork, Subnet, SecurityGroup, VirtualMachine,
                             #   ContainerPlatform, LoadBalancer
    custom_workloads.ts      # Workload, Function
    storage.ts               # ObjectStorage, RelationalDbms, RelationalDatabase
    messaging.ts             # Broker, MessagingEntity
    big_data.ts              # DistributedDataProcessing, ComputeCluster, DataProcessingJob,
                             #   MlExperiment, Datalake
    api_management.ts        # ApiGateway
    observability.ts         # Monitoring, Tracing, Logging
    security.ts              # ServiceMesh, IdentityProvider
  offers/          # Concrete Offers (Level 3) declaring what Component they satisfy
    <domain>.ts    # one file per domain, mirroring components/
  *.test.ts        # vitest specs — the executable regression suite

See docs/fractal-model.md for the locked model specification.

Contributing and feedback

Contributions and feedback are welcome.

See CONTRIBUTING.md for contribution guidelines. Use GitHub Issues for bugs and feature requests, and GitHub Discussions for design questions.

License

Licensed under AGPLv3. See the LICENSE file for details.

Made with ❤️ by the Fractal Cloud team.