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

@bagelink/workspace

v1.10.17

Published

Monorepo workspace tooling for Bagel projects with proxy and config management

Readme

@bagelink/workspace

Workspace tooling for Bagel projects - works for both single projects and monorepos.

Features

  • 🔧 Simple Configuration: One config file for all environments
  • 🔀 Proxy Management: Vite dev proxy + Netlify production redirects
  • 🏗️ Build Tooling: Auto-generate netlify.toml with environment injection
  • 📦 Monorepo Support: Cascading config for multi-project setups

Installation

pnpm add @bagelink/workspace

Quick Start

Option 1: Run npx bgl init (Recommended)

npx bgl init

🔧 No bgl.config.ts found. Let's create one!

? What is your Bagel project ID? › my-project
? Use custom production host? › No / Yes
? Add/update dev scripts in package.json? › Yes
? Create/update vite.config.ts? › Yes
? Generate netlify.toml for deployment? › Yes

✅ Created bgl.config.ts
   Production host: https://my-project.bagel.to
   Local dev host: http://localhost:8000

✅ Updated package.json with dev scripts
✅ Created vite.config.ts
✅ Generated netlify.toml

This will:

  • Create bgl.config.ts with your project configuration
  • Add/overwrite dev and dev:local scripts in package.json
  • Create vite.config.ts with proxy configuration (if doesn't exist)
  • Generate netlify.toml with production proxy configuration

Option 2: Automatic on first use

The first time you use @bagelink/workspace, it will automatically prompt you to create a config file if it doesn't exist.

Option 3: Create manually

Create bgl.config.ts:

import { defineWorkspace } from '@bagelink/workspace'
import type { WorkspaceConfig, WorkspaceEnvironment } from '@bagelink/workspace'

/**
 * Define your workspace environments
 * You can add as many custom environments as needed (e.g., 'staging', 'preview')
 * Use --mode flag to switch: bgl dev --mode <env_name>
 */
const configs: Record<WorkspaceEnvironment, WorkspaceConfig> = {
  localhost: {
    host: 'http://localhost:8000',
    proxy: '/api', // Optional: remove to skip proxy setup
    openapi_url: 'http://localhost:8000/openapi.json',
  },
  development: {
    host: 'https://project.bagel.to',
    proxy: '/api',
    openapi_url: 'https://project.bagel.to/openapi.json',
  },
  production: {
    host: 'https://project.bagel.to',
    proxy: '/api',
  },
  // Add your own custom environments
  staging: {
    host: 'https://staging.project.bagel.to',
    proxy: '/api',
  },
}

export default defineWorkspace(configs)

Usage

1. Add Type Definitions

Add to your project's env.d.ts:

/// <reference types="@bagelink/workspace/env" />

This provides TypeScript types for injected environment variables.

2. Configure Vite (vite.config.ts)

Recommended: Use the Vite plugin (keeps your config clean and standard)

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { bagelink } from '@bagelink/workspace/vite'
import workspace from './bgl.config'

export default defineConfig({
  plugins: [
    vue(),
    bagelink({ workspace }),
  ],
})

The plugin automatically:

  • Configures proxy based on bgl.config.ts
  • Sets up @ alias pointing to ./src
  • Sets up @shared alias (in monorepos)
  • Keeps your vite.config.ts clean and extensible

Advanced: Custom options

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { bagelink } from '@bagelink/workspace/vite'
import { fileURLToPath } from 'node:url'
import workspace from './bgl.config'

export default defineConfig({
  plugins: [
    vue(),
    bagelink({
      workspace,
      config: {
        sharedPath: '../packages/shared',
        additionalAliases: {
          '@utils': fileURLToPath(new URL('./src/utils', import.meta.url))
        }
      }
    }),
  ],
})

Legacy: Manual proxy setup

import { defineConfig } from 'vite'
import { createViteProxy } from '@bagelink/workspace'
import workspace from './bgl.config'

export default defineConfig(({ mode }) => {
  const config = workspace(mode as WorkspaceEnvironment)
  
  return {
    plugins: [vue()],
    server: {
      proxy: createViteProxy(config)
    }
  }
})

3. Use Configuration in Your App

Access config at runtime with useWorkspace():

import { useWorkspace, getApiUrl } from '@bagelink/workspace'

// In your app setup
const { baseURL, proxy, host, mode } = useWorkspace()
const auth = createAuth({ baseURL }) // Uses proxy if available, otherwise host

// Or get full API URL
const apiUrl = getApiUrl() // 'https://project.bagel.to/api'

Vue component example:

<script setup lang="ts">
import { useWorkspace } from '@bagelink/workspace'
import { createAuth } from '@bagelink/auth'

const { baseURL, proxy, host, mode } = useWorkspace()
const auth = createAuth({ baseURL }) // Uses proxy if available, otherwise host

console.log('API Host:', host)
console.log('Environment:', mode)
</script>

Access raw environment variables:

// These are injected at build time by the bagelink plugin
const proxy = import.meta.env.VITE_BGL_PROXY        // '/api'
const host = import.meta.env.VITE_BGL_HOST          // 'https://project.bagel.to'
const openapi = import.meta.env.VITE_BGL_OPENAPI_URL // optional

4. Add scripts to package.json

{
  "scripts": {
    "dev": "vite",
    "dev:local": "vite --mode localhost",
    "dev:staging": "vite --mode staging",
    "build": "vite build",
    "build:staging": "vite build --mode staging"
  }
}

5. Custom Environments

You can define as many custom environments as you need. The environment name is completely flexible:

const configs: Record<WorkspaceEnvironment, WorkspaceConfig> = {
  localhost: {
    host: 'http://localhost:8000',
    proxy: '/api',
  },
  development: {
    host: 'https://dev.project.bagel.to',
    proxy: '/api',
  },
  staging: {
    host: 'https://staging.project.bagel.to',
    proxy: '/api',
  },
  preview: {
    host: 'https://preview.project.bagel.to',
    // No proxy - will use host directly
  },
  production: {
    host: 'https://project.bagel.to',
    proxy: '/api',
  },
}

Use the --mode flag to switch environments:

# Development
bgl dev --mode development

# Staging
bgl dev --mode staging

# Production build
bgl build --mode production

Note: The proxy field is optional. If omitted, no proxy will be configured for that environment, and baseURL from useWorkspace() will return the host value instead.

6. Generate Netlify Config

import { writeNetlifyConfig } from '@bagelink/workspace'
import workspace from './bgl.config'

const config = workspace('production')
writeNetlifyConfig(config, './netlify.toml')

Monorepo Support

Root Config (/bgl.config.ts)

import { defineWorkspace } from '@bagelink/workspace'

export default defineWorkspace({
  localhost: {
    host: 'http://localhost:8000',
    proxy: '/api',
  },
  development: {
    host: 'https://shared.bagel.to',
    proxy: '/api',
  },
  production: {
    host: 'https://shared.bagel.to',
    proxy: '/api',
  },
})

Project Override (/projects/admin/bgl.config.ts)

import { defineWorkspace } from '@bagelink/workspace'
import rootWorkspace from '../../bgl.config'

export default defineWorkspace({
  localhost: rootWorkspace('localhost'),
  development: rootWorkspace('development'),
  production: {
    ...rootWorkspace('production'),
    host: 'https://admin.bagel.to', // Override
  },
})

CLI

Single Project Setup

npx bgl init

Interactively generate project configuration files:

  • bgl.config.ts - Workspace configuration
  • package.json - Add/update dev scripts (optional)
  • vite.config.ts - Vite proxy configuration (optional)
  • netlify.toml - Netlify deployment configuration (optional)
npx bgl init

Features:

  • Prompts for project ID and host configuration
  • Adds/overwrites dev and dev:local scripts in package.json
  • Creates vite.config.ts with proxy setup (if doesn't exist)
  • Generates netlify.toml with production proxy configuration
  • Safe: prompts before each step

Workspace (Multi-Project) Setup

npx bgl init --workspace

Create a workspace with flat structure for multiple projects:

npx bgl init --workspace

? Workspace name: › my-workspace
? Bagel project ID: › my-project
? Create first project? › Yes
? First project name: › web

✅ Workspace created successfully!

Creates structure:

my-workspace/
├── package.json          # Workspace root
├── bgl.config.ts         # Shared config
├── tsconfig.json
├── shared/               # Shared code
│   ├── package.json
│   ├── utils/
│   └── types/
└── web/                  # First project
    ├── bgl.config.ts
    ├── package.json
    ├── vite.config.ts
    └── src/

bgl add <project-name>

Add a new project to workspace:

bgl add admin
bgl add customer
bgl add mobile

Each project:

  • Gets its own directory at root level
  • Inherits shared config from workspace root
  • Can import from shared/utils, shared/types, etc.
  • Auto-configures with Vite proxy

bgl list

List all projects in workspace:

bgl list

Projects:
  - web
  - admin
  - customer

Running Workspace Projects

# Run all projects concurrently
bun run dev

# Run specific project
bun run dev:admin
bun run dev:customer

# Build specific project
bun run build:admin

# Build all projects
bun run build

Vite automatically assigns ports:

  • First project: http://localhost:5173
  • Second project: http://localhost:5174
  • Third project: http://localhost:5175
  • etc.

Linting Setup

bgl lint init

Set up linting and formatting in your project:

bgl lint init

? Select configurations to set up:
  ✔ ESLint
  ✔ Prettier
  ✔ EditorConfig
  ○ Git Hooks
? Install dependencies? › Yes

✅ Created eslint.config.js
✅ Created .prettierrc
✅ Created .prettierignore
✅ Created .editorconfig
✅ Updated package.json with lint scripts

Creates:

  • eslint.config.js - ESLint configuration (Vue 3 + TypeScript)
  • .prettierrc - Prettier configuration
  • .prettierignore - Prettier ignore patterns
  • .editorconfig - Editor configuration
  • .lintstagedrc - Lint-staged configuration (if git hooks selected)

Adds scripts:

  • bun run lint - Run linter
  • bun run lint:fix - Fix linting issues
  • bun run format - Format code
  • bun run format:check - Check formatting

Auto-detects workspace:

# In workspace root (auto-detected)
bgl lint init
✓ Detected workspace mode
# Sets up at workspace root

# In single project (auto-detected)
bgl lint init
# Sets up in current project

# Force modes:
bgl lint init --workspace  # Force workspace mode
bgl lint init --project    # Force single project mode

Workspace detection:

  • Checks for workspaces field in package.json
  • Checks for multiple project directories
  • Auto-applies best mode

SDK Generation

bgl sdk generate

Generate TypeScript SDK from OpenAPI specification:

bgl sdk generate

? OpenAPI spec URL: › http://localhost:8000/openapi.json
? Output directory: › ./src/api
? Split into organized files? › Yes

📡 Fetching OpenAPI spec from: http://localhost:8000/openapi.json
📁 Output directory: ./src/api

✅ Generated types.d.ts
✅ Generated api.ts
✅ Generated index.ts
🔀 Splitting into organized files...
✅ Files organized into directories

✅ SDK generated successfully!

Import it in your code:
  import { api } from './api'

Features:

  • Auto-reads openapi_url from bgl.config.ts
  • Generates TypeScript types from OpenAPI schema
  • Creates type-safe API client
  • Optional file organization (split by endpoints)
  • Works with both local and remote OpenAPI specs

Auto-detects workspace:

# In workspace root (auto-detected)
bgl sdk generate
✓ Detected workspace mode - will generate for multiple projects

? Select projects to generate SDK for:
  ✔ admin
  ✔ customer
  ✔ mobile

# In single project (auto-detected)
bgl sdk generate
# Generates SDK for current project only

# Force modes:
bgl sdk generate --workspace  # Force workspace mode
bgl sdk generate --project    # Force single project mode

Smart behavior:

  • Auto-detects workspace structure
  • Prompts for project selection in workspace mode
  • Reads openapi_url from each project's bgl.config.ts

Generated structure:

src/api/
├── index.ts          # Main export
├── types.d.ts        # TypeScript types
└── api.ts            # API client

# Or with --split:
src/api/
├── endpoints/
│   ├── users.ts
│   ├── auth.ts
│   └── data.ts
├── types/
│   └── index.ts
└── index.ts

npx bgl --help

Show CLI help.

API

Runtime Functions

useWorkspace()

Get workspace configuration at runtime. Config is injected as environment variables during build.

import { useWorkspace } from '@bagelink/workspace'

const { baseURL, proxy, host, openapiUrl, mode } = useWorkspace()

Returns:

interface RuntimeWorkspaceConfig {
  baseURL: string        // proxy if available, otherwise host
  proxy?: string         // '/api' (optional)
  host: string           // 'https://project.bagel.to'
  openapiUrl?: string    // optional
  mode: string           // current environment (e.g., 'localhost', 'development', 'staging')
}

getApiUrl()

Get the full API URL by combining host and proxy.

import { getApiUrl } from '@bagelink/workspace'

const apiUrl = getApiUrl() // 'https://project.bagel.to/api'

Configuration Functions

defineWorkspace(configs)

Define workspace configuration for all environments.

const workspace = defineWorkspace({
  local: { host: 'http://localhost:8000', proxy: '/api' },
  development: { host: 'https://project.bagel.to', proxy: '/api' },
  production: { host: 'https://project.bagel.to', proxy: '/api' },
})

generateWorkspaceConfig(root?, configFile?)

Interactively generate a bgl.config.ts file (called automatically when no config is found).

generateWorkspaceConfigSync(projectId, root?, configFile?, customHost?)

Generate a bgl.config.ts file programmatically.

import { generateWorkspaceConfigSync } from '@bagelink/workspace'

generateWorkspaceConfigSync('my-project')
// Creates bgl.config.ts with host: https://my-project.bagel.to

createWorkspace(options?)

Create workspace instance with async config resolution (for advanced monorepo setups).

const workspace = createWorkspace({ root: process.cwd() })

const config = await workspace.getConfig('production')
const proxy = workspace.createProxy(config)
workspace.generateNetlify(config, './netlify.toml')

Build-Time Functions

These are available from @bagelink/workspace/vite:

createViteProxy(config)

Generate Vite proxy configuration.

import { createViteProxy } from '@bagelink/workspace/vite'

writeNetlifyConfig(config, outPath?, additionalConfig?)

Generate and write netlify.toml file.

import { writeNetlifyConfig } from '@bagelink/workspace/vite'

setBuildEnvVars(config)

Set environment variables for build process:

  • BGL_PROXY_PATH - Proxy path (e.g., /api)
  • BGL_API_HOST - API host URL
  • BGL_OPENAPI_URL - OpenAPI specification URL
import { setBuildEnvVars } from '@bagelink/workspace/vite'

License

MIT © Bagel Studio