i99dash docs
Guides

Type-only imports

When to use `i99dash/types` vs the main entry, and why both exist.

Both runtime packages publish a type-only subpath. Use it when you need a SHAPE but never a RUNTIME.

// Pulls the type only — emits zero JavaScript.
import type { MiniAppContext, CarStatus } from 'i99dash/types';
import type { CommandTemplate } from 'i99dash/types';

The dist artifact for /types contains a single empty .js file (literally 40 bytes after minification — the ESM module marker). Tree-shakers drop it entirely.

When you actually want this

ScenarioUse /types?
Server-rendered page that types a prop as MiniAppContext✓ Yes
Shared schema package referenced by both mini-app + backend✓ Yes
Pure-TypeScript helper that maps a CarStatus to a UI tree✓ Yes (works in Node, web worker, deno)
Anything that calls MiniAppClient.fromWindow()✗ No — needs the runtime
Tests that exercise the Bridge interface✗ No — needs the runtime for withBridge

Why it exists

  • SSR cleanliness. Importing the runtime SDK from a Next.js server component pulls a dependency that calls window defensively. No actual error, but webpack lights up the SSR-incompatibility warning. import type from '/types' skips the whole branch.
  • Bundle visibility. A consumer who sees import type { X } from 'i99dash/types' knows by inspection that this code path doesn't add bytes to the runtime bundle. With a regular type-only import from 'i99dash', you have to trust the bundler is doing dead-code-elimination correctly.
  • Cross-package use without duplication. Your shared schemas package can import type { CarStatus } from /types without pulling the rest of the SDK into its own dependency tree.

What's exported from /types

Same wire types you'd get from the main entry, plus the type aliases that go with them. Names match i99dash exactly.

i99dash/types:

type MiniAppContext;
type MiniAppManifest;       // incl. the `network` egress allow-list

type CarStatus;
type CarStatusStaleness;    // 'fresh' | 'stale' | 'very_stale'
type CarConnectionState;    // 'connected' | 'disconnected'
type CarDoors;
type CarDoorState;          // 'open' | 'closed'

type CallOptions;
type SDKErrorCode;
type Bridge;
type CarStatusBridge;
type HostBridgeApi;
type WindowWithHost;

type CarStatusListener;
type CarConnectionListener;

i99dash/types:

type AdminClientContext;
type AdminClientOptions;
type InvokeOptions;

type AdminBridge;
type AdminExecRequest;

type AdminOpResponse<T = unknown>;
type CapabilityResponse;
type CatalogSnapshot;
type CommandTemplate;
type ParamRule;

Caveats

  • No runtime symbols are exported. If you write import { CarStatusSchema } from 'i99dash/types' (note: not import type), TypeScript will let you (the schema is in the source), but at runtime it'll be undefined. Use the main entry for schemas: import { CarStatusSchema } from 'i99dash' (the wire-types package).
  • No re-exports. /types is a flat list; there's no i99dash/types/car subpath. Keeps the bundle audit simple.
  • enum would be a runtime. None of the type-only exports are enums — they're string-literal unions or interfaces. Future schema additions follow the same rule.

On this page