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

@smooai/config

v2.1.4

Published

Type-safe multi-language configuration management with schema validation, three-tier config (public, secret, feature flags), and runtime client support for TypeScript, Python, Rust, and Go.

Downloads

1,067

Readme

About SmooAI

SmooAI is an AI-powered platform for helping businesses multiply their customer, employee, and developer experience.

Learn more on smoo.ai

SmooAI Packages

Check out other SmooAI packages at smoo.ai/open-source

About @smooai/config

Type-safe configuration management for every layer of your stack - Define configuration schemas once, validate everywhere, and manage public settings, secrets, and feature flags across TypeScript, Python, Rust, and Go.

NPM Version NPM Downloads NPM Last Update

GitHub License GitHub Actions Workflow Status GitHub Repo stars

Why @smooai/config?

Ever scattered configuration values across environment variables, JSON files, and hardcoded strings? Or struggled to keep configuration consistent across microservices written in different languages? Traditional config management gives you the values, but not the safety.

@smooai/config provides:

  • Three configuration tiers - Separate public config, secrets, and feature flags with distinct schemas
  • Schema-agnostic validation - Works with Zod, Valibot, ArkType, Effect Schema, or any StandardSchema-compliant library
  • Type-safe keys - Automatic camelCase-to-UPPER_SNAKE_CASE mapping with full TypeScript inference
  • JSON Schema serialization - Convert any schema to JSON Schema for cross-language interoperability
  • Runtime client - Fetch configuration from a centralized config server with local caching
  • Multi-language support - Native implementations in TypeScript, Python, Rust, and Go

Install

TypeScript / JavaScript

pnpm add @smooai/config

Python

pip install smooai-config

or with uv:

uv add smooai-config

Rust

[dependencies]
smooai-config = { git = "https://github.com/SmooAI/config", package = "smooai-config" }

Go

go get github.com/SmooAI/config/go/config

TypeScript Setup

Add .smooai-config/**/*.ts to your tsconfig.json so TypeScript processes your configuration files:

{
  "compilerOptions": { ... },
  "include": ["src/**/*", ".smooai-config/**/*.ts"]
}

Or if you prefer a separate tsconfig for the config directory, create .smooai-config/tsconfig.json:

{
    "extends": "../tsconfig.json",
    "include": ["./**/*.ts"]
}

Usage

TypeScript - Define Configuration Schemas

Use any StandardSchema-compliant validation library to define your configuration:

import { defineConfig, StringSchema, BooleanSchema, NumberSchema } from '@smooai/config';
import { z } from 'zod';

const config = defineConfig({
    publicConfigSchema: {
        apiUrl: z.string().url(),
        maxRetries: NumberSchema,
        enableDebug: BooleanSchema,
    },
    secretConfigSchema: {
        databaseUrl: z.string().url(),
        apiKey: StringSchema,
    },
    featureFlagSchema: {
        enableNewUI: BooleanSchema,
        betaFeatures: BooleanSchema,
    },
});

Supports Zod, Valibot, ArkType, Effect Schema, and built-in schema types - see SCHEMA_USAGE.md for examples with each library.

Python - Define and Fetch Configuration

from pydantic import BaseModel
from smooai_config import define_config, ConfigTier
from smooai_config.client import ConfigClient

# Define schemas using Pydantic models
class PublicConfig(BaseModel):
    api_url: str = "https://api.example.com"
    max_retries: int = 3

class SecretConfig(BaseModel):
    database_url: str
    api_key: str

config = define_config(
    public=PublicConfig,
    secret=SecretConfig,
)

# Fetch values at runtime
with ConfigClient(
    base_url="https://config.smooai.dev",
    api_key="your-api-key",
    org_id="your-org-id",
) as client:
    value = client.get_value("API_URL", environment="production")
    all_values = client.get_all_values(environment="production")

Rust - Define and Fetch Configuration

use smooai_config::{define_config, ConfigTier};
use smooai_config::client::ConfigClient;

// Define configuration tiers
let config = define_config(
    Some(vec![("api_url", "https://api.example.com")]),
    Some(vec![("database_url", "postgres://...")]),
    None,
);

// Fetch values at runtime
let client = ConfigClient::new(
    "https://config.smooai.dev",
    "your-api-key",
    "your-org-id",
);
let value = client.get_value("API_URL", Some("production")).await?;

Go - Define and Fetch Configuration

import "github.com/SmooAI/config/go/config"

// Define configuration
cfg := config.DefineConfig(
    map[string]interface{}{"apiUrl": "https://api.example.com"},
    map[string]interface{}{"databaseUrl": "postgres://..."},
    nil,
)

// Fetch values at runtime
client := config.NewConfigClient(
    "https://config.smooai.dev",
    "your-api-key",
    "your-org-id",
)
defer client.Close()
value, err := client.GetValue("API_URL", "production")
allValues, err := client.GetAllValues("production")

SDK Runtime Client

All language implementations include a runtime client for fetching configuration values from the Smoo AI config server. Each client supports local caching and environment variable configuration.

Environment Variables

All clients read from the same set of environment variables:

| Variable | Description | Required | | ----------------------- | ------------------------------------------------------ | -------- | | SMOOAI_CONFIG_API_URL | Base URL of the config API | Yes | | SMOOAI_CONFIG_API_KEY | Bearer token for authentication | Yes | | SMOOAI_CONFIG_ORG_ID | Organization ID | Yes | | SMOOAI_CONFIG_ENV | Default environment name (defaults to "development") | No |

Set these in your environment and the client will use them automatically:

export SMOOAI_CONFIG_API_URL="https://config.smooai.dev"
export SMOOAI_CONFIG_API_KEY="your-api-key"
export SMOOAI_CONFIG_ORG_ID="your-org-id"
export SMOOAI_CONFIG_ENV="production"

TypeScript SDK Client

The TypeScript client works in any JavaScript runtime (Node.js, browsers, edge runtimes):

import { ConfigClient } from '@smooai/config/platform/client';

// Option 1: Use environment variables (zero-config)
const client = new ConfigClient();

// Option 2: Explicit configuration (overrides env vars)
const client = new ConfigClient({
    baseUrl: 'https://config.smooai.dev',
    apiKey: 'your-api-key',
    orgId: 'your-org-id',
    environment: 'production',
});

// Fetch a single value (uses default environment)
const apiUrl = await client.getValue('API_URL');

// Fetch a value for a specific environment
const stagingUrl = await client.getValue('API_URL', 'staging');

// Fetch all values
const allValues = await client.getAllValues();

// Clear the local cache
client.invalidateCache();

React Hooks

For React applications, use the built-in hooks with ConfigProvider:

import { ConfigProvider, usePublicConfig, useSecretConfig, useFeatureFlag } from '@smooai/config/react';

// Wrap your app with ConfigProvider
function App() {
    return (
        <ConfigProvider baseUrl="https://config.smooai.dev" apiKey="your-api-key" orgId="your-org-id" environment="production">
            <MyComponent />
        </ConfigProvider>
    );
}

// Use hooks in any child component
function MyComponent() {
    const { value: apiUrl, isLoading, error } = usePublicConfig<string>('API_URL');
    const { value: dbUrl } = useSecretConfig<string>('DATABASE_URL');
    const { value: enableNewUI, refetch } = useFeatureFlag<boolean>('ENABLE_NEW_UI');

    if (isLoading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return <div>API URL: {apiUrl}</div>;
}

Next.js Integration

For Next.js applications, use getConfig in Server Components and SmooConfigProvider to pass values to client components with zero loading flash:

// app/layout.tsx (Server Component)
import { getConfig, SmooConfigProvider } from '@smooai/config/nextjs';

export default async function RootLayout({ children }: { children: React.ReactNode }) {
    const config = await getConfig({
        environment: 'production',
        fetchOptions: { next: { revalidate: 60 } }, // ISR: revalidate every 60s
    });

    return (
        <html>
            <body>
                <SmooConfigProvider
                    initialValues={config}
                    baseUrl={process.env.SMOOAI_CONFIG_API_URL}
                    apiKey={process.env.SMOOAI_CONFIG_API_KEY}
                    orgId={process.env.SMOOAI_CONFIG_ORG_ID}
                    environment="production"
                >
                    {children}
                </SmooConfigProvider>
            </body>
        </html>
    );
}

// Any client component — values are available synchronously (no loading flash)
import { usePublicConfig, useFeatureFlag } from '@smooai/config/nextjs';

function MyComponent() {
    const { value: apiUrl } = usePublicConfig<string>('API_URL'); // Instant — pre-seeded from SSR
    const { value: enableNewUI } = useFeatureFlag<boolean>('ENABLE_NEW_UI');
    return <div>API: {apiUrl}</div>;
}

Vite React Integration

For Vite-based React apps, call preloadConfig() before mounting React to start fetching early:

// main.tsx
import { preloadConfig } from '@smooai/config/vite';
import { ConfigProvider } from '@smooai/config/vite';
import { createRoot } from 'react-dom/client';

// Start fetching config immediately (before React renders)
preloadConfig({ environment: 'production' });

createRoot(document.getElementById('root')!).render(
    <ConfigProvider baseUrl="https://config.smooai.dev" apiKey="your-public-key" orgId="your-org-id" environment="production">
        <App />
    </ConfigProvider>,
);

Python SDK Client

from smooai_config.client import ConfigClient

# Option 1: Use environment variables (zero-config)
with ConfigClient() as client:
    value = client.get_value("API_URL")
    all_values = client.get_all_values()

# Option 2: Explicit configuration
with ConfigClient(
    base_url="https://config.smooai.dev",
    api_key="your-api-key",
    org_id="your-org-id",
    environment="production",
) as client:
    value = client.get_value("API_URL")
    value = client.get_value("API_URL", environment="staging")  # Override environment

Rust SDK Client

use smooai_config::client::ConfigClient;

// Option 1: Use environment variables (zero-config)
let mut client = ConfigClient::from_env();

// Option 2: Explicit configuration
let mut client = ConfigClient::new(
    "https://config.smooai.dev",
    "your-api-key",
    "your-org-id",
);

// Option 3: Explicit with default environment
let mut client = ConfigClient::with_environment(
    "https://config.smooai.dev",
    "your-api-key",
    "your-org-id",
    "production",
);

// Fetch values (None uses default environment)
let value = client.get_value("API_URL", None).await?;
let value = client.get_value("API_URL", Some("staging")).await?;
let all = client.get_all_values(None).await?;

Go SDK Client

import "github.com/SmooAI/config/go/config"

// Option 1: Use environment variables (zero-config)
client := config.NewConfigClientFromEnv()
defer client.Close()

// Option 2: Explicit configuration (empty strings fall back to env vars)
client := config.NewConfigClient(
    "https://config.smooai.dev",
    "your-api-key",
    "your-org-id",
)
defer client.Close()

// Fetch values (empty string uses default environment)
value, err := client.GetValue("API_URL", "")
value, err := client.GetValue("API_URL", "staging")
allValues, err := client.GetAllValues("")

Configuration Tiers

| Tier | Purpose | Examples | | ----------------- | ----------------------- | ---------------------------------------- | | Public | Client-visible settings | API URLs, feature toggles, UI config | | Secret | Server-side only | Database URLs, API keys, JWT secrets | | Feature Flags | Runtime toggles | A/B tests, gradual rollouts, beta access |

Each tier gets its own schema, validation, and JSON Schema output for cross-language consumption.

Security: B2M Key Restrictions

The Smoo AI Config API enforces tier-based access control depending on the API key type:

| Operation | B2M (Public Key) | M2M (Secret Key) | | -------------------- | ----------------- | ---------------- | | Read public values | Yes | Yes | | Read feature flags | Yes | Yes | | Read secret values | No (filtered) | Yes | | Write config values | No (403) | Yes | | Delete config values | No (403) | Yes |

Browser-to-Machine (B2M) keys are designed for browser-based clients. Secret-tier values are automatically filtered from bulk responses and return 403 for individual lookups. B2M keys are read-only for public and feature flag tiers.

Machine-to-Machine (M2M) keys have full access to all tiers and write operations.

Development

Prerequisites

  • Node.js 22+, pnpm 10+
  • Python 3.13+ with uv
  • Rust toolchain (rustup)
  • Go 1.22+

Commands

pnpm install               # Install dependencies
pnpm build                 # Build all packages (TS, Python, Rust, Go)
pnpm test                  # Run all tests (Vitest, pytest, cargo test, go test)
pnpm lint                  # Lint all code (oxlint, ruff, clippy, go vet)
pnpm format                # Format all code (oxfmt, ruff, cargo fmt, gofmt)
pnpm typecheck             # Type check (tsc, basedpyright, cargo check)
pnpm check-all             # Full CI parity check

Built With

  • TypeScript - Core implementation with StandardSchema support
  • Python - Pydantic-based schemas with httpx runtime client
  • Rust - Serde-based schemas with reqwest async client
  • Go - Native schemas with net/http client and local caching
  • StandardSchema - Schema-agnostic validation
  • Zod, Valibot, ArkType, Effect - Supported validation libraries

Contributing

Contributions are welcome! This project uses changesets to manage versions and releases.

Development Workflow

  1. Fork the repository

  2. Create your branch (git checkout -b amazing-feature)

  3. Make your changes

  4. Add a changeset to document your changes:

    pnpm changeset

    This will prompt you to:

    • Choose the type of version bump (patch, minor, or major)
    • Provide a description of the changes
  5. Commit your changes (git commit -m 'Add some amazing feature')

  6. Push to the branch (git push origin feature/amazing-feature)

  7. Open a Pull Request

Pull Request Guidelines

  • Reference any related issues in your PR description

The maintainers will review your PR and may request changes before merging.

Contact

Brent Rager

Smoo Github: https://github.com/SmooAI