# @firecms/neat 中文文档

规范地址：https://npmcn.com/package/%40firecms/neat/

版本：1\.1\.1
npm 元数据更新时间：2026-11-08T21:34:26.528Z
中文译文更新时间：2026-11-14T19:34:31.205Z
软件包许可：SEE LICENSE IN LICENSE

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40firecms/neat
原文对照：https://npmcn.com/package/%40firecms/neat/?lang=original
项目主页：https://github.com/FireCMSco/neat#readme
源码仓库：https://github.com/FireCMSco/neat

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.4 MB，42 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2023-11-22T22:38:41.077Z
- 最新版本发布：2026-11-08T21:34:26.325Z
- 近 30 天下载量：47398（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：34（近 12 个月 23 个）

## 中文简介

您网站美丽的 三维梯度

## 安装

```sh
npm install @firecms/neat
```

也可以使用：`pnpm add @firecms/neat`、`yarn add @firecms/neat`、`bun add @firecms/neat`

## README

# \*

以硬件加速的WebGL性能创建出惊人,动画的3D梯度.

[![npm version](https://badge.fury.io/js/@firecms%2Fneat.svg)](https://www.npmjs.com/package/@firecms/neat) [![License: MIT + Commons Clause](https://img.shields.io/badge/License-MIT%20%2B%20Commons%20Clause-lightgrey.svg)](https://github.com/FireCMSco/neat/blob/main/LICENSE)

**✨ [尝试交互式编辑器](https://neat.rebase.pro/) ✨**

用我们的视觉编辑器设计完美的梯度, 以20+预设和实时预览为特色. 导出配置并立即在您的工程中使用 .

![Neat Gradient Examples](https://neat.rebase.pro/og_image_v3.png)

* * *

## \* 安装

```bash
npm install @firecms/neat
```

或者说

```bash
yarn add @firecms/neat
```

* * *

## QQ 快速启动

### 基本用途

```typescript
import { NeatGradient } from "@firecms/neat";

const gradient = new NeatGradient({
    ref: document.getElementById("canvas"),
    colors: [
        { color: "#FF5772", enabled: true },
        { color: "#4CB4BB", enabled: true },
        { color: "#FFC600", enabled: true },
        { color: "#8B6AE6", enabled: true },
        { color: "#2E0EC7", enabled: true }
    ],
    speed: 4,
    waveAmplitude: 5,
    backgroundColor: "#003FFF",
    backgroundAlpha: 1
});

// Clean up when done (important for React, Vue, etc.)
gradient.destroy();
```

### 反应示例

```tsx
import { useEffect, useRef } from "react";
import { NeatGradient, NeatConfig } from "@firecms/neat";

function BackgroundGradient() {
    const canvasRef = useRef<HTMLCanvasElement>(null);
    const gradientRef = useRef<NeatGradient | null>(null);

    useEffect(() => {
        if (!canvasRef.current) return;

        gradientRef.current = new NeatGradient({
            ref: canvasRef.current,
            colors: [
                { color: "#FF5772", enabled: true },
                { color: "#4CB4BB", enabled: true },
                { color: "#FFC600", enabled: true }
            ],
            speed: 3,
            waveAmplitude: 5
        });

        return () => gradientRef.current?.destroy();
    }, []);

    return (
        <canvas
            ref={canvasRef}
            style={{
                position: "fixed",
                top: 0,
                left: 0,
                width: "100%",
                height: "100%",
                zIndex: -1
            }}
        />
    );
}
```

* * *

## 配置 API

### 核心动画

| 财产 | 类型 | 默认 | 范围 | 说明 |
| --- | --- | --- | --- | --- |
| `speed` | `number` | `4` | `0-10` | 动画速度 (0 = 静态) |
| `waveAmplitude` | `number` | `3` | `0-10` | 波高强度 |
| `waveFrequencyX` | `number` | `5` | `0-10` | 水平波频率 |
| `waveFrequencyY` | `number` | `5` | `0-10` | 垂直波频率 |

### 颜色

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `colors` | `NeatColor[]` | 需求 | 颜色对象阵列( 最多为 6) |
| `colorBlending` | `number` | `5` | 颜色如何混合( 0- 10) |
| `colorBrightness` | `number` | `1` | 总体亮度乘数 |
| `colorSaturation` | `number` | `0` | 颜色饱和度调整( 10- 10) |
| `horizontalPressure` | `number` | `3` | 水平颜色分布( 0- 10) |
| `verticalPressure` | `number` | `3` | 垂直颜色分布( 0- 10) |

**颜色对象 :**

```typescript
{
    color: string;      // Hex color (e.g., "#FF5772")
    enabled: boolean;   // Toggle color on/off
    influence?: number; // Color strength (0-1, optional)
}
```

### 视觉效果

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `shadows` | `number` | `4` | 阴影强度 (0-10) |
| `highlights` | `number` | `4` | 突出显示强度( 0- 10) |
| `grainIntensity` | `number` | `0.55` | 胶片谷物数量(0-1) |
| `grainScale` | `number` | `2` | 谷物大小 |
| `grainSparsity` | `number` | `0.0` | 谷物分配螺旋性 (0-1) |
| `grainSpeed` | `number` | `0.1` | 谷物动画速度 |
| `wireframe` | `boolean` | `false` | 显示线框网格 |

### 高级阴影处理后处理( P)

#### 域旋转

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `domainWarpEnabled` | `boolean` | `false` | 启用域扭曲 |
| `domainWarpIntensity` | `number` | `0.5` | 域名拼接的强度 |
| `domainWarpScale` | `number` | `1.0` | 旋转的空间频率尺度 |

#### 维尼特

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `vignetteIntensity` | `number` | `0.0` | 角落的黑暗强度( 0-1) |
| `vignetteRadius` | `number` | `0.8` | 放射坠落起始距离 |

#### 弗雷斯内尔( Rim Glow)

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `fresnelEnabled` | `boolean` | `false` | 启用外缘阴影效果 |
| `fresnelPower` | `number` | `2.0` | 轮回的光芒 |
| `fresnelIntensity` | `number` | `0.5` | 发光效果的亮度 |
| `fresnelColor` | `string` | `"#FFFFFF"` | 环形发光的颜色( hex) |

#### 迷恋

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `iridescenceEnabled` | `boolean` | `false` | 启用肥皂泡样式颜色转换 |
| `iridescenceIntensity` | `number` | `0.5` | 颜色转变效应的强度 |
| `iridescenceSpeed` | `number` | `1.0` | 颜色循环速度 |

#### 布鲁姆( 假花花)

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `bloomIntensity` | `number` | `0.0` | 从亮点出血的发光强度 |
| `bloomThreshold` | `number` | `0.7` | 开花候选像素的亮度阈值 |

#### 染色异常

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `chromaticAberration` | `number` | `0.0` | 镜头彩色通道分割距离 |

### 3D 地美图和形状

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `shapeType` | `'plane' | 'sphere' | 'torus' | 'cylinder' | 'ribbon'` | `'plane'` | 3D 形状几何使梯度在 |
| `shapeRotationX` | `number` | `0` | 手动 X 旋转(弧度) |
| `shapeRotationY` | `number` | `0` | 手动 Y 旋转( 弧度) |
| `shapeRotationZ` | `number` | `0` | 手动 Z 旋转(弧度) |
| `shapeAutoRotateSpeedX` | `number` | `0` | X 轴上的自动旋转速度 |
| `shapeAutoRotateSpeedY` | `number` | `0` | Y 轴上的自动旋转速度 |
| `sphereRadius` | `number` | `15` | 球体形状的半径 |
| `torusRadius` | `number` | `15` | 托鲁斯主环半径 |
| `torusTube` | `number` | `5` | Torus 内管厚度 |
| `cylinderRadius` | `number` | `10` | 圆柱形半径 |
| `cylinderHeight` | `number` | `40` | 圆柱形状的高度 |
| `planeBend` | `number` | `0` | 应用在平面几何上的 Bding 扭曲 |
| `planeTwist` | `number` | `0` | 对平面几何应用的扭曲 |
| `silhouetteFade` | `number` | `0.25` | 球体/托盘的边缘透明度逐渐消失 |
| `cylinderFade` | `number` | `0.08` | 向气瓶末端的透明化 |
| `ribbonFade` | `number` | `0.05` | 透明度向着丝带的尽头消失 |
| `flatShading` | `boolean` | `true` | 对几何常态使用平面阴影 |

### 相机设置

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `cameraLock` | `boolean` | `false` | 锁定相机控制并阻止拖动旋转 |
| `cameraX` | `number` | `0` | 相机沿 X 轴进行偏移 |
| `cameraY` | `number` | `0` | Y轴相机偏移 |
| `cameraZ` | `number` | `0` | 相机沿 Z 轴偏移 |
| `cameraRotationX` | `number` | `0` | 相机弹出旋转(弧度) |
| `cameraRotationY` | `number` | `0` | 相机 yaw 旋转(弧度) |
| `cameraRotationZ` | `number` | `0` | 相机滚动旋转(弧度) |
| `cameraZoom` | `number` | `1.0` | 相机缩放因子 |

### 背景情况

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `backgroundColor` | `string` | `"#FFFFFF"` | 背景颜色 (hex) |
| `backgroundAlpha` | `number` | `1` | 背景不透明(0-1) |

### 业绩

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `resolution` | `number` | `1` | 网格密度(0.1-2,较低=业绩更好) |
| `renderScale` | `number` | `1` | 相对于画布的 CSS 大小( 0.1-3) 绘制缓冲大小 |

**`resolution` 是网格密度,而不是像素分辨率.** 它缩小了流离失所的规模 网格 - 平面的240x240段 `1`,120x120 用于3D形状. 大多数 每帧成本在顶点阴影中,所以这是第一个拒绝. 网格也上限为每6个帆布像素大约一个段,所以很小 帆布从不支付它不能显示的细节.

**`renderScale` 是像素的一个.** 时 `0.75` 梯度使像素减少44% 和浏览器对结果进行分级——通常在内容后面看不见 在低端设备上最便宜的赢家. 它需要CSS的画布大小;如果 布局大小来自宽度/高度属性,缩放被忽略(带有 因此元素不能在每次调整大小时缩小.

**`speed: 0` 毫无代价.** 时钟停了 每一帧都是一样的, 因此,渲染环形公园本身, 只有在你改变一个属性时才醒来。 一个静态 梯度是一次性的渲染,而不是60英尺重绘相同的图像.

### 滚动集成

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `yOffset` | `number` | `0` | 垂直滚动偏移 |
| `yOffsetWaveMultiplier` | `number` | `4` | 卷轴对波浪的影响有多大(0-20) |
| `yOffsetColorMultiplier` | `number` | `4` | 卷轴影响颜色多少( 0-20) |
| `yOffsetFlowMultiplier` | `number` | `4` | 卷轴影响流量字段多少( 0-20) |

### 流场( 扭曲)

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `flowEnabled` | `boolean` | `true` | 启用流量字段扭曲 |
| `flowDistortionA` | `number` | `0` | 主扭曲振幅 |
| `flowDistortionB` | `number` | `0` | 二次扭曲频率 |
| `flowScale` | `number` | `1` | 外地总流量规模 |
| `flowEase` | `number` | `0` | 流场平滑 (0-1) |

### 程序性纹理重叠

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `enableProceduralTexture` | `boolean` | `false` | 启用纹理覆盖 |
| `textureMode` | `'bitmap' | 'baked'` | `'bitmap'` | 纹理如何绘制——见下文 |
| `textureBakeResolution` | `number` | `0` | 烧焦纹理大小; 0 从画布取出 |
| `bakeEdgeSoftness` | `number` | `1` | 烘焙时反变相宽度, 单位为输出特克塞尔 |
| `textureVoidLikelihood` | `number` | `0.45` | 纹理相隔频率 (0-1) |
| `textureVoidWidthMin` | `number` | `200` | 最小空隙宽度 |
| `textureVoidWidthMax` | `number` | `486` | 最大间隙宽度 |
| `textureBandDensity` | `number` | `2.15` | 纹理带密度 |
| `textureColorBlending` | `number` | `0.01` | 纹理中的颜色混合 (0-1) |
| `textureSeed` | `number` | `333` | 纹理随机种子 |
| `textureEase` | `number` | `0.5` | 流量/图像混合 (0=流量, 1=图像) |
| `transparentTextureVoid` | `boolean` | `false` | 显示为透明而非使用程序背景颜色 |
| `proceduralBackgroundColor` | `string` | `"#000000"` | 纹理空白颜色 |
| `textureShapeTriangles` | `number` | `20` | 三角形状数 |
| `textureShapeCircles` | `number` | `15` | 圆形数 |
| `textureShapeBars` | `number` | `15` | 条形状数 |
| `textureShapeSquiggles` | `number` | `10` | 螺旋形状数量 |

#### 位图对已烤

`textureMode` 决定上面的形状如何被引入纹理中。 两者 模式读取相同的生成的相片, 所以给定 `textureSeed` 生产 无论哪种方式, 和相同的组成, 和两者最终作为一个普通的 迷雾纹理—— 运行时间成本相同。 不同的是纹理有多尖.

**`bitmap`** (默认)以1024px的硬码通过Canvas2D来绘制形状. 边缘落在网格上 一旦相机放大了纹理 它们就会软化 和对角显示 楼梯步入 他们的网格上.

**`baked`** 对 GPU 进行光栅化分析:精确的每像素 边缘覆盖,以来自画布而不是固定的分辨率表示。 没错 两者生成的速度也越快 全屏英雄的 Canvas2D 路径,因为它跳过 CPU 绘图和 上传.

|  | `bitmap` | `baked` |
| --- | --- | --- |
| 决议 | 1024,总是 | 从帆布, 1024–2048 (4096 选入) |
| 边缘质量 | Canvas2D 防伪 | 精确分析覆盖率 |
| 生成 | ~35分钟 | ~20 ms 时 |
| 运行时间 | 一个纹理获取 | 一个纹理获取 |
| 内存 | ~5.5 MB 键 | ~22 MB 于 2048 时 |

须知三限:

-   **烘焙时不支持抽屉** 并被弃去警告. Cubic Béziers 没有封闭式的相距功能,所以成本很高 大约是其他形状的十倍.
-   **`baked` 需要网络GL2** (单位:千美元)`texelFetch` 和浮起的纹理 `bitmap` 否则。 读取 `activeTextureMode` 用于实际使用的模式.
-   **记忆是每个实例.** WebGL 纹理无法在上下文之间共享, 和每个 `NeatGradient` 拥有自己的画布和上下文,所以有一个页面带有 他们中有几个人每人付费。 这就是为什么2048年的默认上限 4096岁以上 `textureBakeResolution` 故意的 故意的.

```js
const gradient = new NeatGradient({
    ref: canvas,
    enableProceduralTexture: true,
    textureMode: "baked",
    textureShapeSquiggles: 0,   // not available when baking
    textureBakeResolution: 0,   // 0 = derive from the canvas
    bakeEdgeSoftness: 1.0,      // antialiasing width, in output texels
    // ...
});

gradient.activeTextureMode; // 'baked', or 'bitmap' if it had to fall back
gradient.textureMode = "bitmap"; // switchable at runtime
```

* * *

## API 方法

### `destroy()`

清理 WebGL 上下文,事件收听器,并删除任何被注入的 DOM 元素. 当组件卸载防止内存出漏时调用此功能( React, Vue等必需).

```typescript
gradient.destroy();
```

* * *

## QQ 动态属性更新

所有属性都可以实时更新 :

```typescript
// Animation
gradient.speed = 6;
gradient.waveAmplitude = 8;

// Colors
gradient.colors = [
    { color: "#FF0000", enabled: true },
    { color: "#00FF00", enabled: true }
];

// 3D Shape Geometries & Auto-Rotation
gradient.shapeType = "sphere";
gradient.shapeAutoRotateSpeedY = 1.5;

// Advanced Post-Processing Effects
gradient.iridescenceEnabled = true;
gradient.fresnelEnabled = true;
gradient.fresnelColor = "#FF0055";

// Effects
gradient.grainIntensity = 0.5;

// Texture
gradient.enableProceduralTexture = true;
gradient.textureEase = 0.7;
```

## 一个梯度,许多画布

浏览器只授予少数活的 WebGL 语境, 以及每个额外的 `NeatGradient` 运行自己的阴影。 所以不要每张牌创造一张 —— 创建 **一个** 渐变和镜像 随你喜欢的平地2D画布 每个镜子可以显示不同的收成, 他们都保持完美的同步,每个镜像的成本是GPU副本而不是一个 第二次妥协.

就是这样 [编辑器](https://neat.rebase.pro/) 将梯度预览为 a 网站英雄,手机屏幕和一行相声同时出现.

源梯度需要 `preserveDrawingBuffer: true` 没有它,绘图缓冲 在堆肥后清除, 并且没有可用的副本 :

```typescript
import { NeatGradient } from "@firecms/neat";

const source = document.getElementById("source") as HTMLCanvasElement;

const gradient = new NeatGradient({
    ref: source,
    preserveDrawingBuffer: true,   // required to read the canvas from outside its own frame
    colors: [
        { color: "#FF5772", enabled: true },
        { color: "#4CB4BB", enabled: true },
        { color: "#FFC600", enabled: true }
    ]
});
```

然后在任何你想去的地方 照照它的区域:

```typescript
type MirrorOptions = {
    cx?: number;    // horizontal centre of the crop, 0–1
    cy?: number;    // vertical centre of the crop, 0–1
    zoom?: number;  // 1 shows as much as fits, 2 shows half
    fps?: number;   // refresh rate — drop it for small decorative mirrors
};

function mirror(target: HTMLCanvasElement, options: MirrorOptions = {}) {
    const { cx = 0.5, cy = 0.5, zoom = 1, fps = 60 } = options;
    const ctx = target.getContext("2d");
    const interval = 1000 / fps;
    let raf = 0;
    let last = 0;

    const draw = (now: number) => {
        raf = requestAnimationFrame(draw);
        if (!ctx || now - last < interval) return;
        last = now;

        const dpr = Math.min(window.devicePixelRatio || 1, 2);
        const w = Math.round(target.clientWidth * dpr);
        const h = Math.round(target.clientHeight * dpr);
        if (!w || !h || !source.width || !source.height) return;
        if (target.width !== w || target.height !== h) {
            target.width = w;
            target.height = h;
        }

        // Largest crop of the source matching the target's aspect ratio, then zoomed
        const aspect = w / h;
        let cropW = source.width;
        let cropH = source.width / aspect;
        if (cropH > source.height) {
            cropH = source.height;
            cropW = source.height * aspect;
        }
        cropW /= zoom;
        cropH /= zoom;

        const sx = Math.min(Math.max(cx * source.width - cropW / 2, 0), source.width - cropW);
        const sy = Math.min(Math.max(cy * source.height - cropH / 2, 0), source.height - cropH);

        ctx.clearRect(0, 0, w, h);
        ctx.drawImage(source, sx, sy, cropW, cropH, 0, 0, w, h);
    };

    raf = requestAnimationFrame(draw);
    return () => cancelAnimationFrame(raf);
}

// A hero, a tight crop for a card, and a slow-refreshing avatar
mirror(document.getElementById("hero") as HTMLCanvasElement);
mirror(document.getElementById("card") as HTMLCanvasElement, { cx: 0.3, cy: 0.4, zoom: 1.7 });
mirror(document.getElementById("avatar") as HTMLCanvasElement, { cx: 0.7, cy: 0.6, zoom: 10, fps: 10 });
```

**值得我们知道的事**

-   源头帆布必须保持布局. `display: none` 折叠到零大小 渐变停止渲染——用 `position: fixed; inset: 0; z-index: -1` 或者用不透明的层层遮住.
-   使用一个 `requestAnimationFrame` 环绕所有镜像而非每个镜像;示例 上面是模糊的,但有一个共享的勾动器,可以更好地显示列表的比分.
-   `drawImage` 从 WebGL 画布上看到一个跨文本副本——在桌面上很便宜,很显著 在电话。 在那里,将设备像素比上限为1,运行镜像比为30英尺,并给出 小的装饰花花(avatar,图标) 10 fps. 没人知道40px圈.
-   镜子是普通的画布,所以它们取 `border-radius`, (中文(简体) ), `mask-image`, (中文(简体) ), `filter` 还有CSS提供的其他东西 小小的镜子模糊到无所事事 使环境变得很好 在布局后面发光.
-   只有源头需要 `preserveDrawingBuffer`。这也是什么使 `downloadAsPNG()` 和视频拍摄工作.

* * *

## QQ 类型脚本支持

完整类型脚本定义包括:

```typescript
import { NeatGradient, NeatConfig, NeatColor, NeatController } from "@firecms/neat";

const config: NeatConfig = {
    // ... fully typed config
};

const gradient: NeatController = new NeatGradient(config);
```

* * *

## 许可证

Neat 将在 **麻省理工学院许可证+共同条款**。 。 。 .

**你可以这样:**

-   \* 个人项目自由使用
-   在商业项目中自由使用(例如SaaS登陆页,公司网站)
-   修改和再分配(带有归属)
-   用于开源项目

**你不能说:**

-   卖出软件
-   将它包含在您出售的付费模板或主题构建器中
-   提供软件作为有偿服务

### 删除 NEAT 水印

为 **12欧元一次性** (每个域名)去除NEAT水印和控制台品牌.

**[购买执照](https://neat.rebase.pro/)**

然后通过您配置中的密钥 :

```typescript
const gradient = new NeatGradient({
    ref: canvas,
    colors: [...],
    licenseKey: "NEAT-eyJ0eXBlI..."  // Your license key
});
```

每个密钥被锁入您在退出时指定的域( 包含子域) 。 联合国 `localhost` 总是没有钥匙的.

同样的密钥从 PNG 和视频输出中移除了水印 [编辑器](https://neat.rebase.pro/): 单击 **支持**,则 **激活您的密钥**把它粘起来.

* * *

## • 信贷

创建于 [重新基地](https://rebase.pro/) 与

* * *

## 问题和贡献

找到错误还是有特性请求 ?

-   **问题:** [GitHub 问题](https://github.com/FireCMSco/neat/issues)
-   **讨论:** [GitHub 讨论](https://github.com/FireCMSco/neat/discussions)

* * *

## 链接

-   🌐 [网站编辑器( E)](https://neat.rebase.pro/)
-   📦 [npm 软件包](https://www.npmjs.com/package/@firecms/neat)
-   💻 [GitHub 仓库](https://github.com/FireCMSco/neat)
-   💬 [迪斯科德社区](https://discord.gg/fxy7xsQm3m)

* * *

**由基地团队制作**

## 常见问题

### @firecms/neat 是什么？

您网站美丽的 三维梯度

### 如何安装 @firecms/neat？

在项目目录运行 npm install @firecms/neat，或使用 pnpm add / yarn add / bun add。

### @firecms/neat 支持 TypeScript 吗？

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

### @firecms/neat 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @firecms/neat 可以商用吗？

@firecms/neat 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中，请阅读该文件确认可否商用。以上为概括，不构成法律意见，请以许可原文为准。

### @firecms/neat 的下载量有多少？

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

### @firecms/neat 还在维护吗？

最新版本 1\.1\.1 发布于 2026/11/09（5 天前）；至今共发布 34 个版本，其中过去 12 个月发布了 23 个；首次发布于 2023/11/23。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

