@docspack/lapis

中文文档
0.3.0发布于 2026/10/03MITTypeScriptES Module近 30 天下载 2.4万

Convert an OpenAPI 3 document to LAPIS, the compact notation for describing an API to a language model. About 90% fewer tokens than the same document as JSON.

原始使用文档
文档目录7 节
  1. As a library
  2. The model
  3. Three limits, and the measurement behind each
  4. Conformance
  5. What it refuses
  6. Who uses it
  7. Licence

@docspack/lapis

OpenAPI 3 in, LAPIS out. About 90% fewer tokens than the same document as JSON.

LAPIS is an open notation for describing an API to a language model rather than to a code generator: a signature per operation, compact types, and the sections OpenAPI spends thousands of lines on collapsed into a few. There was no JavaScript converter for it, so this is one.

npx @docspack/lapis ./openapi.yaml
npx @docspack/lapis ./openapi.json -o api.lapis --stats
curl -s https://example.com/openapi.json | npx @docspack/lapis - > api.lapis
[meta]
api: Invoice Service
base: https://api.example.com/v2
auth: bearer header:Authorization

[types]
InvoiceCreate:
  customer_id: str
  due_date?: date

[ops]
create_invoice POST /invoices
  Creates an invoice for a customer.
  > body: InvoiceCreate
  < Invoice  # 201 The created invoice.
  @auth bearerAuth

[errors]
401 ApiError
  The token is missing, expired or invalid.

Measured against Stripe's published document — 594 operations, 1,454 schemas, 8.0 MB:

594 operations, 1454 types, read as json
~193,593 tokens of LAPIS, against ~2,163,446 of JSON (91% smaller)

As a library

import { parseOpenApi, toLapis } from "@docspack/lapis";

const document = parseOpenApi(await someOpenApiObject);
toLapis(document);

parseOpenApi resolves every $ref, merges allOf, and keeps named schemas by name so a recursive document terminates. It takes an already-parsed object, so this entry point has no dependencies and runs anywhere — including a browser.

Reading a file, or text that might be YAML, is a separate entry point:

import { readApiFile, readApiText } from "@docspack/lapis/read";

const { document, format } = await readApiFile("./openapi.yaml"); // format: "json" | "yaml"

That split is the point of the package's shape. JSON.parse is built into every JavaScript runtime at zero bytes; YAML needs a parser, and that parser is ~57 KB gzipped. Putting it behind /read means a browser bundling parseOpenApi and toLapis ships none of it, and tests/entry.test.ts asserts that over the built output rather than trusting the comment.

The model

Both renderings come from one shape — ApiDocument, with operations, types, servers, securitySchemes and tags. It is exported, so it is also usable on its own if you want a normalized OpenAPI document and not LAPIS at all. toGroups(document) buckets operations by tag for a sidebar.

Three limits, and the measurement behind each

A faithful renderer produces unusable output on real documents. Each of these exists because its absence was measured against Stripe's spec:

LimitWithout it
Type closure stops at a token budgetEvery Stripe object has an expandable field pointing at another, so one operation reaches most of the API: 66,500 tokens for one endpoint
Enumerations list 8 membersThe merchant-category enum has 297, four times in one operation: 25,637 characters on one line
Inline objects expand 2 levels, 12 fieldsA document that names no schemas renders its whole body tree inline

Everything elided is counted — +32 more, {...} — because "there is more to this shape" and "this is the whole shape" are different claims, and only one of them is true.

Conformance

One thing here is not in LAPIS's grammar: an @auth <scheme> line on an operation. LAPIS declares authentication in [meta] and has no per-operation form, so a document where some endpoints are public and others are not — which is most of them — cannot say so in conformant LAPIS. It is emitted by default because that is worth more to a model than conformance is, and turned off by --strict (or toLapis(document, { strict: true })) for anything feeding a parser that would reject it.

Everything else is legal LAPIS: # comments carry the success status, and [errors] is the format's own section — declared once per document, with @ops: bindings where an error is not universal.

What it refuses

Each of these stops with the command to run:

  • Swagger 2.0 — npx swagger2openapi openapi.json -o openapi3.json
  • An external $ref — npx @redocly/cli bundle openapi.yaml -o openapi.json. Refused rather than dropped: a schema silently replaced by "unknown" is a description claiming an endpoint takes no body.
  • A $ref that points at nothing — named, with the pointer.

Who uses it

This package is the shared half of docspack's OpenAPI support. @docspack/openapi builds on it — per-operation digests, request building, code samples, a try-it console — and docspack build --openapi turns a document into a searchable documentation package. None of that is needed to use this; it converts one format to another and stops.

Licence

MIT. The LAPIS specification is CC BY 4.0 and belongs to its authors; this package implements a renderer for it.

版本与发布记录

@docspack/lapis 共发布 3 个版本,首次发布于 2026/09/11;过去 12 个月发布了 3 个版本。

版本发布日期距今
0.3.0latest2026/10/031 个月前
0.2.02026/09/161 个月前
0.1.02026/09/112 个月前

关于 @docspack/lapis 的常见问题

@docspack/lapis 是什么?

Convert an OpenAPI 3 document to LAPIS, the compact notation for describing an API to a language model. About 90% fewer tokens than the same document as JSON.

如何安装 @docspack/lapis?

在项目目录运行 npm install @docspack/lapis,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 lapis,可以用 npx lapis 直接运行。

@docspack/lapis 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@docspack/lapis 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@docspack/lapis 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.5.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@docspack/lapis 可以商用吗?

@docspack/lapis 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@docspack/lapis 的下载量有多少?

根据 npm 官方下载统计,@docspack/lapis 在 2026/10/13 – 2026/11/11 这 30 天内被下载 24,342 次,日均约 811 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@docspack/lapis 还在维护吗?

最新版本 0.3.0 发布于 2026/10/03(1 个月前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/09/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。