Skip to content

Proposal: CDN Usage Guide for TypeScript Projects #996

@Qsppl

Description

@Qsppl

Hi team! I've prepared a guide for using Orbit.js via CDN in TypeScript projects without bundlers. It covers:

  • CDN imports with full TypeScript support
  • tsconfig.json setup
  • Cross-dependency resolution

Would you consider adding this to the official docs? Here's the full guide:

CDN Usage Guide for TypeScript Projects

This guide explains how to use Orbit.js with CDN imports while maintaining full TypeScript support in ESNext projects without bundlers.

Installation

First, install Orbit.js packages locally to get type definitions:

npm install @orbit/jsonapi @orbit/records

ES2015/ES6/ES2020/ES2022/ESNext

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "paths": {
       // Names for Orbit CDN Package Imports
       "https://esm.sh/@orbit/jsonapi": ["node_modules/@orbit/jsonapi/dist/modules/index"],
       "https://esm.sh/@orbit/records": ["node_modules/@orbit/records/dist/modules/index"],

       // For cross-package imports
       "@orbit/coordinator": ["node_modules/@orbit/coordinator/dist/modules/index"],
       "@orbit/core": ["node_modules/@orbit/core/dist/modules/index"],
       "@orbit/data": ["node_modules/@orbit/data/dist/modules/index"],
       "@orbit/identity-map": ["node_modules/@orbit/identity-map/dist/modules/index"],
       "@orbit/immutable": ["node_modules/@orbit/immutable/dist/modules/index"],
       "@orbit/indexeddb": ["node_modules/@orbit/indexeddb/dist/modules/index"],
       "@orbit/indexeddb-bucket": ["node_modules/@orbit/indexeddb-bucket/dist/modules/index"],
       "@orbit/jsonapi": ["node_modules/@orbit/jsonapi/dist/modules/index"],
       "@orbit/local-storage": ["node_modules/@orbit/local-storage/dist/modules/index"],
       "@orbit/local-storage-bucket": ["node_modules/@orbit/local-storage-bucket/dist/modules/index"],
       "@orbit/memory": ["node_modules/@orbit/memory/dist/modules/index"],
       "@orbit/record-cache": ["node_modules/@orbit/record-cache/dist/modules/index"],
       "@orbit/records": ["node_modules/@orbit/records/dist/modules/index"],
       "@orbit/serializers": ["node_modules/@orbit/serializers/dist/modules/index"],
       "@orbit/utils": ["node_modules/@orbit/utils/dist/modules/index"],
       "@orbit/validators": ["node_modules/@orbit/validators/dist/modules/index"],
    }
  }
}

The same pattern works for all Orbit.js packages:

  • @orbit/coordinator
  • @orbit/identity-map
  • @orbit/indexeddb
  • @orbit/local-storage
  • @orbit/memory
  • @orbit/utils
  • etc.

Simply follow the same URL pattern:

"https://esm.sh/@orbit/<package>@<version>": ["node_modules/@orbit/<package>/dist/modules/index"]
// For cross-package imports
"@orbit/<package>": ["node_modules/@orbit/<package>/dist/modules/index"]

Node16/Node18/NodeNext

Just use module declarations:

// global.d.ts
declare module "https://cdn.investprojects.info/@orbit/core@0.17.0" {
  export * from "@orbit/core";
}

Usage Example

import JSONAPISource from "https://cdn.investprojects.info/@orbit/jsonapi"
import { RecordSchema } from "https://cdn.investprojects.info/@orbit/records"

const schema = new RecordSchema({
  models: {
    planet: {
      attributes: {
        name: { type: "string" },
        classification: { type: "string" },
        atmosphere: { type: "boolean" },
      },
      relationships: {
        moons: { kind: "hasMany", type: "moon", inverse: "planet" },
      },
    },
    moon: {
      attributes: {
        name: { type: "string" },
      },
      relationships: {
        planet: { kind: "hasOne", type: "planet", inverse: "moons" },
      },
    },
  },
})

const remote = new JSONAPISource({
  schema: schema,
  host: "/my-entry",
})

Key Points

  1. Version Pinning: Always specify package versions in CDN URLs
  2. Path Resolution: TypeScript finds types via paths mapping
  3. No Bundler Needed: Works with native browser ESM
  4. Cross-Package Dependencies: Internal imports are resolved through local node_modules

Troubleshooting

If types aren't being resolved:

  1. Verify paths point to existing files in node_modules
  2. Run tsc --traceResolution to debug path resolution
  3. If your server's web root is not set to "/" but to "/web", "/public", etc., then this needs to be explicitly specified in your tsconfig:
    {
    "compilerOptions": {
        "target": "ES2022",
        "module": "ESNext",
        "baseUrl": "./web/",
        "paths": {
        // NOT "node_modules/...", BUT "../node_modules/..." relative by "baseUrl"!
        "https://esm.sh/@orbit/coordinator": ["../node_modules/@orbit/coordinator/dist/modules/index"],
        "https://esm.sh/@orbit/core": ["../node_modules/@orbit/core/dist/modules/index"],
        ...
        }
    }
    }

Why This Works

  • The paths setting redirects CDN imports to local type definitions
  • Local npm packages provide complete type information

This could help developers who need CDN-based workflows while keeping type safety.

This guide provides a complete solution for:
✅ CDN usage with type safety
✅ No bundler required
✅ Cross-package dependency resolution
✅ Clean developer experience

Would you like me to make any adjustments before you submit it to the Orbit.js repository?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions