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

sampo-config

v0.0.2-alpha.2

Published

Embeddable Mihomo/Clash config generator for React + Vite + Tailwind v4 apps. Powered by sampo-editor.

Readme

sampo-config

npm (alpha) status: alpha license: MIT

Embeddable Mihomo/Clash config generator for React + Vite + Tailwind v4 apps.

Live demo: https://sampo-config.uji69i.workers.dev/

Drop <MihomoConfigGenerator /> into your app, wrap it in I18nProvider + a router, bring Tailwind v4 with the provided theme, and the full UI of the generator becomes available.

All mihomo-specific knowledge — the form-meta catalogue, the JSON Schema used for YAML validation, and the Monaco editor itself — lives in sampo-editor, which sampo-config consumes as a peer dependency. Edit form-meta YAML once, get both the generator UI and the Monaco editor hints updated.

Installation

pnpm add sampo-config sampo-editor react react-dom react-router-dom

Peer dependencies:

  • react / react-dom ^19
  • react-router-dom ^7<MihomoConfigGenerator /> reads location.state for warp proxies handoff, so it must be mounted inside a router.
  • sampo-editor — provides Monaco editor components, the mihomo JSON Schema and form-meta data. Exposed via sampo-editor/presets/mihomo.

Tailwind v4 setup

sampo-config ships Tailwind source files and a @theme inline block. Tailwind must be run by the consumer (no prebuilt CSS in dist).

In your app's main CSS file:

@import "tailwindcss";
@import "sampo-config/styles.css";
@import "sampo-editor/editor.css";

@source "../node_modules/sampo-config/dist";
@source "../node_modules/sampo-editor/dist";

The @source directives tell Tailwind's JIT to scan the compiled library files so the required utility classes end up in your bundle.

Dark mode is toggled by placing the dark class on any ancestor of the generator (commonly <html>). sampo-config does not ship a theme provider — use your own or toggle the class manually.

Usage

import { StrictMode, useState } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import { initMonaco } from 'sampo-editor'

import {
  MihomoConfigGenerator,
  I18nProvider,
  type Locale,
} from 'sampo-config'

import './app.css' // your CSS entry with the @import / @source lines above

initMonaco() // wires Monaco web workers — call once at app startup

function App() {
  const [locale, setLocale] = useState<Locale>('en')
  return (
    <I18nProvider locale={locale} setLocale={setLocale}>
      <BrowserRouter>
        <MihomoConfigGenerator />
      </BrowserRouter>
    </I18nProvider>
  )
}

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

The mihomo JSON Schema is bundled inside sampo-editor/presets/mihomo and wired into Monaco automatically by <YamlOutput /> — you do not need to serve any mihomo.schema.json file yourself.

Public API

import {
  // Main generator
  MihomoConfigGenerator,

  // Reducer (for custom integrations)
  mihomoReducer,
  createInitialState,
  type MihomoAction,

  // i18n
  I18nProvider,
  useTranslation,
  I18nContext,
  LOCALES,
  LOCALE_LABEL_KEYS,
  type Locale,
  type I18nContextValue,

  // UI helpers
  LocaleSwitcher,
  type LocaleSwitcherProps,

  // Utilities
  cn,
  getRejectPolicyClassName,
  getDataBaseUrl,

  // Mihomo state / serialization
  type MihomoState,
  type MihomoProxy,
  type ServiceTemplate,
  buildFullConfig,
  parseYamlToState,
  serializeStateToUrl,
  MAX_URL_LENGTH,
} from 'sampo-config'

For form-meta data, the mihomo JSON Schema, or to localize the schema descriptions, import directly from sampo-editor/presets/mihomo.

Local development

pnpm install
pnpm dev           # vite playground at http://localhost:5173
pnpm typecheck
pnpm test
pnpm build         # library build → dist/ (ESM, .d.ts, styles.css)
pnpm build:site    # playground as a static site → dist-site/
pnpm build:single  # playground as one inlined HTML file → dist-single/index.html
pnpm build:all     # all three above in sequence
pnpm preflight     # typecheck + test + build (what CI runs)

sampo-editor is installed from npm. For local development against a sibling checkout, use pnpm link ../sampo-editor after pnpm install — this replaces the npm copy with a symlink to your local build. Run pnpm install to revert.

The dev/ directory hosts a minimal playground that imports the library via the @/ alias (the same way a consumer would import from sampo-config).

Editing the mihomo form-meta

Form-meta YAML lives in sampo-editor/form-meta/. After editing anything there, run pnpm build:presets (or pnpm build) inside sampo-editor to regenerate presets/mihomo/generated/*. sampo-config picks up the changes via pnpm link on the next dev server restart or build.

The hand-maintained TypeScript interfaces for the mihomo runtime config shape live at src/lib/mihomo/generated/config-types.ts and are treated as a regular source file — not regenerated automatically.

Releasing

Publishing is automated via .github/workflows/publish.yml. Trigger it by pushing a v* tag that matches package.json version:

# 1. Bump version in package.json + update CHANGELOG.md
# 2. Commit the bump, push to main
# 3. Tag + push:
git tag v0.0.1
git push origin v0.0.1

The workflow refuses to publish if the tag does not match the version field. One-time setup: add an npm automation token as the NPM_TOKEN repository secret.

prepublishOnly runs pnpm preflight (typecheck + test + build) locally if you ever pnpm publish by hand.

Contributing

See CONTRIBUTING.md for the quick start, the PR checklist, and the split between what belongs in sampo-config vs. sampo-editor. For architectural context (why CSS is shipped raw, why sampo-editor is a peer dependency, how the manual-edit flow works, etc.) read CLAUDE.md.

License

MIT — © 2026 uji69i and sampo-config contributors.