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

@codelifter/sdk

v0.4.7

Published

Codelifter SDK — programmatic API for UI extraction and code generation (built-in adapters: react/vue/svelte/react-native/flutter, custom adapter API, optional internal escape hatch)

Readme

@codelifter/sdk

Surface 4/8 — the builder's lane. High-level API to embed Codelifter in your tool.

The SDK is the surface for builders — Raycast extension authors, Figma plugin developers, VS Code extension authors, and SaaS teams embedding "URL → component code" into their own product. v0.3.0 ships the high-level API (extract, streamExtract, detectLibraries) plus the Custom Adapter API (registerAdapter for React Native, Solid, Flutter, …); low-level escape hatches live behind @codelifter/sdk/internal.

VSCode/Figma/Raycast 익스텐션은 v1.0.3 에 함께 출시되었으며 — 이 SDK 가 그 셋의 공통 토대입니다. 이 패키지는 그 셋의 외부 빌더에게도 동일하게 열려 있습니다.


Why SDK?

Codelifter has 8 user-facing surfaces today (browser, AI editor MCP, terminal CLI, Node.js SDK, Claude Code skill, VSCode/Cursor extension, Figma plugin, Raycast extension). The SDK is the builders' lane — the one external builders use when they want to plug Codelifter's extraction engine into their own tool, without owning a Chromium install or a WebSocket protocol. (We also use it ourselves as the backbone of surfaces 6–8.)

Personas the SDK targets:

  • Raycast extension authors — Cmd+Space, type a URL, get React on clipboard.
  • Figma plugin developers — accept a URL, return Figma node tree from the detected library.
  • VS Code / Cursor / JetBrains extension authors — command palette → URL → editor.
  • SaaS embedders — your own dashboard offers "import from URL"; you call extract() server-side.

The SDK guarantees:

  1. Same engine as the browser extension (Tier 2 library detection — shadcn/ui, Radix, MUI, etc).
  2. Automatic fallback — extension bridge → headless Playwright → CDP, no code change needed.
  3. AbortSignal + onProgress — your UI gets first-class progress, your user can cancel.
  4. Streaming via async iterator — for editors with long-lived progress UI.

Install

npm install @codelifter/sdk

Quickstart

extract — single-shot

import { extract } from '@codelifter/sdk';

const result = await extract('https://stripe.com/payments', {
  framework: 'react',
  cssMode: 'tailwind',
});

console.log(result.pipelineMode);
// 'extension' | 'headless-bundled' | 'headless-remote'
console.log(result.extractionResult);

streamExtract — async iterator with progress

import { streamExtract } from '@codelifter/sdk';

for await (const event of streamExtract('https://stripe.com/payments')) {
  if (event.type === 'progress') {
    statusBar.show(event.event.message ?? event.event.phase);
  } else if (event.type === 'library-detected') {
    console.log('Detected:', event.library.name, event.library.confidence);
  } else if (event.type === 'done') {
    return event.result;
  }
}

detectLibraries — Tier 2 only

import { detectLibraries } from '@codelifter/sdk';

const libs = await detectLibraries('https://ui.shadcn.com');
// [{ name: 'shadcn/ui', category: 'component-framework', confidence: 1 }, ...]

Behind-auth pages (useMyChrome)

// 먼저 별도 터미널에서:
//   npx codelifter connect-my-chrome
// (CDP 9222 포트로 사용자 Chrome 실행, 기존 세션 유지)

const result = await extract('https://app.example.com/dashboard', {
  useMyChrome: true,
  chromePort: 9222,
});

Cancellation + progress

import { extract } from '@codelifter/sdk';

const ac = new AbortController();
setTimeout(() => ac.abort(), 30_000); // 30s timeout

try {
  const result = await extract('https://example.com', {
    signal: ac.signal,
    onProgress: (e) => console.log(e.phase, e.message),
  });
} catch (err) {
  if (ac.signal.aborted) console.log('user cancelled');
}

surface option — funnel attribution (권장)

surface 옵션으로 호출 진입점을 명시하면 백엔드가 surface별 funnel을 분리 측정합니다.

// 직접 SDK 호출 (기본값)
await extract(url, { surface: 'sdk' });

// Raycast extension 내부에서 호출
await extract(url, { surface: 'raycast' });

// VSCode extension 내부에서 호출
await extract(url, { surface: 'vscode' });

⚠️ Deprecated notice: surface 미지정 시 런타임 경고가 표시됩니다. 다음 메이저 버전에서 필수 파라미터로 변경될 예정입니다. 상위 통합 빌더는 해당 surface 식별자를 명시해주세요.


Builder scenarios

다음 시나리오 셋은 빌더가 SDK 를 자기 도구에 어떻게 박는가의 ready-to-adapt 예시입니다. Codelifter 가 v1.0.3 에서 직접 출시한 IDE/Figma/Raycast 익스텐션의 청사진이기도 합니다.

1. Embed in a Raycast extension

// raycast-extension/src/lift.tsx
import { Detail, popToRoot, showToast, Toast } from '@raycast/api';
import { extract } from '@codelifter/sdk';

export default async function Command(props: { arguments: { url: string } }) {
  const toast = await showToast({ style: Toast.Style.Animated, title: 'Lifting...' });
  const result = await extract(props.arguments.url, {
    onProgress: (e) => (toast.message = e.message),
  });
  await navigator.clipboard.writeText(result.generatedFiles?.[0]?.content ?? '');
  toast.style = Toast.Style.Success;
  toast.title = 'Copied React to clipboard';
  await popToRoot();
}

Raycast 의 ToastonProgress 와 자연스럽게 묶입니다. 사용자는 Cmd+Space → lift <url> → 클립보드에 React 코드, 그게 전부.[^1]

2. Embed in a Figma plugin

// figma-plugin/src/code.ts (백엔드 — Figma sandbox 외부에서 동작)
import { detectLibraries, extract } from '@codelifter/sdk';

figma.ui.onmessage = async (msg) => {
  if (msg.type === 'lift-url') {
    // 1) 라이브러리 빠르게 감지 → UI 에 어떤 디자인 시스템인지 즉시 표시
    const libs = await detectLibraries(msg.url);
    figma.ui.postMessage({ type: 'libraries', libs });

    // 2) 풀 추출 → DOM/CSS 를 Figma node 트리로 매핑
    const result = await extract(msg.url, { framework: 'react' });
    figma.ui.postMessage({ type: 'extracted', result });
  }
};

Figma plugin sandbox 가 Node API 를 제한하므로 실제 SDK 호출은 별도 backend 에서 합니다. detectLibraries 가 가벼워 UI 진행률을 단계별로 채우기 좋습니다.[^1]

3. Embed in a VSCode extension

// vscode-extension/src/extension.ts
import * as vscode from 'vscode';
import { streamExtract } from '@codelifter/sdk';

export function activate(ctx: vscode.ExtensionContext) {
  ctx.subscriptions.push(
    vscode.commands.registerCommand('codelifter.lift', async () => {
      const url = await vscode.window.showInputBox({ prompt: 'URL to lift' });
      if (!url) return;

      await vscode.window.withProgress(
        { location: vscode.ProgressLocation.Notification, title: 'Codelifter', cancellable: true },
        async (progress, token) => {
          const ac = new AbortController();
          token.onCancellationRequested(() => ac.abort());

          for await (const ev of streamExtract(url, { signal: ac.signal })) {
            if (ev.type === 'progress') {
              progress.report({ message: ev.event.message });
            } else if (ev.type === 'done') {
              const file = ev.result.generatedFiles?.[0];
              if (file) {
                const doc = await vscode.workspace.openTextDocument({
                  content: file.content,
                  language: 'typescriptreact',
                });
                await vscode.window.showTextDocument(doc);
              }
            }
          }
        }
      );
    })
  );
}

VS Code 의 withProgress + cancellation token 이 streamExtract + AbortSignal 과 1:1 로 맵 됩니다. command palette → URL → 활성 에디터에 새 .tsx 가 열리는 흐름.[^1]

[^1]: 위 시나리오 셋의 first-party 출시는 Codelifter 가 v1.0.3 에서 직접 진행했습니다 (packages/vscode-extension, packages/figma-plugin, packages/raycast-extension). SDK 는 외부 빌더에게도 동일하게 열려 있어, 이 코드를 그대로 자기 익스텐션에 가져가도 됩니다.


How to get the pairing token

SDK 가 확장 브리지(extension 파이프라인, 100% Tier 2)를 사용할 때는 페어링 토큰이 필요합니다. 토큰 없이도 headless-bundled 모드는 동작합니다 (~95% Tier 2). 100% 보존을 원하면:

  1. Browser Extension 열기 — 툴바의 Codelifter 아이콘 클릭, 사이드 패널의 Settings 탭으로 이동.

  2. Developer integrations 섹션 펼치기 — "MCP server" 카드.

  3. "Enable MCP server" 토글 ON — 토큰이 자동 생성됩니다.

  4. 64자 토큰 표시 — "Show pairing token" 버튼으로 마스킹 해제. 옆의 복사 버튼으로 클립보드에 복사.

  5. SDK 호출 환경에 전달 — 다음 두 방법 중 하나:

    # 방법 1: 환경변수
    export CODELIFTER_MCP_TOKEN=<pasted-64-char-token>
    node my-script.mjs
    
    # 방법 2: config 파일 (영구)
    mkdir -p ~/.config/codelifter
    echo "<pasted-64-char-token>" > ~/.config/codelifter/pairing.token
    chmod 600 ~/.config/codelifter/pairing.token

Security: 토큰은 Codelifter 서버에 절대 전송되지 않습니다. 로컬 WebSocket 핸드쉐이크 (x-codelifter-token 헤더 + crypto.timingSafeEqual 비교) 에만 사용되며, 3 회 실패 시 10 분 차단됩니다.


API reference

extract(url, options?)

| 옵션 | 타입 | 기본값 | 설명 | |------|------|--------|------| | selector | string | — | CSS 선택자 (특정 요소만) | | framework | 'react' \| 'vue' \| 'svelte' \| 'react-native' \| 'flutter' | 'react' | 출력 프레임워크 (RN/Flutter 는 클라이언트 사이드 변환) | | cssMode | 'tailwind' | 'tailwind' | CSS 모드 | | useMyChrome | boolean | false | 사용자 Chrome (CDP) 사용 | | chromePort | number | 9222 | CDP 포트 | | onProgress | (e: ExtractProgressEvent) => void | — | 진행률 콜백 | | signal | AbortSignal | — | 취소 신호 |

streamExtract(url, options?)

extract 와 동일 옵션 + AsyncGenerator<ExtractStreamEvent> 반환. yield 하는 이벤트:

  • { type: 'progress', event } — onProgress 와 동일 페이로드
  • { type: 'library-detected', library } — Tier 2 시그니처 매치 시
  • { type: 'done', result } — 마지막. 호출자가 result 를 사용.

detectLibraries(url, options?)

Tier 2 라이브러리만 빠르게 감지 (코드 생성 비용 회피). 옵션은 extract 의 부분집합 (selector, useMyChrome, chromePort, signal).

Built-in mobile adapters (v0.4.0+)

React Native 와 Flutter adapter 가 SDK 에 기본 동봉됩니다 — registerAdapter 호출 없이 바로 사용:

import { extract } from '@codelifter/sdk';

// React Native — .tsx + StyleSheet.create({...})
const rn = await extract('https://stripe.com/payments', { framework: 'react-native' });
console.log(rn.generatedFiles?.[0]?.path); // 'LiftedScreen.tsx'

// Flutter — .dart + Material widgets
const ft = await extract('https://stripe.com/payments', { framework: 'flutter' });
console.log(ft.generatedFiles?.[0]?.path); // 'liftedscreen.dart'

매핑 정책 — 100% 정확도가 목표가 아님. 빌더가 자기 컴포넌트 라이브러리(Paper, NativeBase, gluestack / Material, Cupertino) 컨벤션으로 추가 가공함을 전제로 한 "의도 보존" 수준의 변환:

| HTML | React Native | Flutter | |------|-------------|---------| | div | View | Container | | p / span / h1~h6 | Text | Text | | img | Image | Image.network | | a / button | Pressable | InkWell + onTap | | input / textarea | TextInput | TextField | | ul / ol | View | Column |

CSS 변환 — padding/margin 분해, color (#rgb/#rrggbb/rgb()/keyword) → Color(0xFFRRGGBB), font-size/weight, border-radius, width/height. 미지원 속성은 무시 (빌더 후가공).

예제: examples/react-native.ts, examples/flutter.ts.

백엔드 영향 — RN/Flutter 변환은 클라이언트 사이드만 — 백엔드는 항상 react 로 호출. v1.0.2 호환성 락 유지.

Custom Adapter API (v0.3.0+)

framework: 'react'|'vue'|'svelte'|'react-native'|'flutter' 외 자기 프레임워크 (Solid, SwiftUI, Compose 등) 를 지원하려면 adapter 를 등록한다.

import { registerAdapter, extract, type CustomAdapter } from '@codelifter/sdk';

const reactNativeAdapter: CustomAdapter = {
  name: 'react-native',
  mapNode(node, ctx) { /* HTML 태그 → RN 컴포넌트 매핑 */ },
  formatOutput(tree, ctx) { /* 트리 → .tsx 파일 */ },
  getImports(libraries, ctx) { /* detected library → import 선언 */ },
};

registerAdapter(reactNativeAdapter);
const result = await extract(url, { framework: 'react-native' });

또는 registerAdapter 없이 객체를 직접 전달:

const result = await extract(url, { framework: reactNativeAdapter });

전체 예제: examples/custom-adapter.ts.

streamExtract 는 adapter 가 등록된 경우 'node-mapped' 이벤트를 추가로 yield 하며, 모든 추출 에러는 'error' 이벤트로 들어온다 (이전엔 그냥 throw 였음).

streamExtract 이벤트 (v0.3.0+)

| type | 발생 조건 | |------|----------| | progress | 단계 변경 (connecting → extracting-dom → transforming-code → done) | | library-detected | Tier 2 시그니처 매치 | | node-mapped | custom adapter 의 mapNode 가 노드 처리 완료 | | done | 추출 + adapter 처리 완료 (마지막 이벤트) | | error | 어느 단계든 실패 (yield 후 throw) |

Timeout

await extract(url, {
  timeoutMs: 30_000, // 30초 후 자동 abort
  signal: ac.signal, // signal 과 함께 쓰면 둘 중 먼저 발생한 abort 적용
});

@codelifter/sdk/internal (escape hatch — 직접 사용 비권장)

import {
  extractViaExtensionBridge,
  isExtensionBridgeAvailable,
  extractViaPlaywright,
  extractViaRemoteChrome,
  streamTransform,
  loadConfig,
  saveConfig,
  getApiKey,
  getApiBaseUrl,
  requireApiKey,
} from '@codelifter/sdk/internal';

이 entry 의 시그니처는 minor 업데이트에서도 깨질 수 있습니다. SDK semver 는 high-level API(/) 에만 적용됩니다.


Related surfaces (8개 모두 Live)

  • Browser Extension (Surface 1/8) — Tier 2 100% 보존의 원천. SDK 는 가능하면 이 확장의 WebSocket 브리지를 우선 시도.
  • MCP Server (Surface 2/8) — codelifter mcp-stdio. SDK 는 이를 직접 부르지 않지만 동일 페어링 토큰을 공유.
  • CLI (@codelifter/cli, Surface 3/8) — SDK 가 internal dependency 로 wrapping. 동일 동작 보장.
  • Claude Code Skill (Surface 5/8) — /codelifter 슬래시. 클립보드/MCP 결과를 .tsx 로 변환.
  • VSCode / Cursor Extension (Surface 6/8) — Command Palette 의 Codelifter: Extract from URL. SDK 위에 박힌 IDE 진입점.
  • Figma Plugin (Surface 7/8) — 라이브 URL 을 Figma frame 으로 lift. SDK backend 호출.
  • Raycast Extension (Surface 8/8) — Cmd+Space → lift <url> → 클립보드 React. SDK 의 extract + onProgress 사용.