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

@ghini/kit

v26.1.3175450

Published

js practical tools to assist efficient development

Readme

@ghini/kit

很厉害的JS库哦,通过示例,轻松上手

基于原生的http,https和http2封装的高性能,拓展性强,安全稳健的httpserver和request,性能远超express,koa,axios,request

所有都是基于高性能,安全及实用性封装

一. 安装及使用

npm i @ghini/kit

导入,所有在kit命名空间下操作,这是推荐的方式:

import kit from "@ghini/kit/dev";

二.快速开始

1. 创建一个httpserver

快速开始,非常实用,用完就离不开的cs(console):
测试文件路径: ./test/t-cs.js

import kit from "@ghini/kit/dev";
kit.cs();
// kit.cs(0);
// kit.cs(1);
// kit.cs(2);
// kit.cs(3);
// kit.cs({
//   dev:{info:3},
// });
// kit.cs({
//   dev:{info:6},
//   err:{info:3},
//   log:{trace:2},
// });
console.log("Let's start!");
console.info("info");
console.debug("debug");
console.warn("warn");
console.error("error");
console.dev("dev");
node --watch ./test/t-console.js

进阶用法: 尝试依序将下方注释解开

3.httpserver

测试文件路径:./test/api/main.js

import kit from "@ghini/kit";
kit.cs();
const server = kit.h2s();
kit.h2s({ allowHTTP1: false });
kit.hss();
kit.hs();
kit.h2s(8080);
server.addr("/", (gold) => gold.json(gold));
server.addr("/post", "post", (gold) => gold.raw("post only"));
server.addr(/regexp/, (gold) => gold.raw("任意包含regexp的路径  Any path that contains regexp"));
console.log(server.routes);

4.request

  • 多路复用✅
  • cookie管理✅
  • 灵活的请求参数处理✅
  • 可复用的参数构造✅
  • 可高度自定义请求头,请求体✅
  • 自动解码br,deflate,zstd,gzip压缩的响应体✅
  • 自动解析json✅ 测试文件路径:./test/t-req.js
import kit from "@ghini/kit/dev";
kit.cs({
  dev: { line: 3 },
});
// 创建http https h2服务器,并设置/test路由
const sarr = await Promise.all([kit.hs(3300), kit.hss(3301), kit.h2s(3302)]);
function fn(g) {
  const { query, data, cookie } = g;
  g.setcookie([`t=${performance.now()};max-age=3600`, "a=1;max-age=3600"]);
  g.json({ query, data, cookie });
}
sarr.forEach((s) => {
  s.addr("/timetout", () => {});
  s.addr("/test", fn);
});

// req使用示例
console.log("超时(错误处理)示例===========================================");
let [res, res1, res2] = await Promise.all([
  kit
    .req("http://localhost:3300/timetout")
    .then((res) => console.log(res) || res),
  kit
    .req("https://localhost:3301/timetout", { cert: false, timeout: 4000 })
    .then((res) => console.log(res) || res),
  kit
    .req("https://localhost:3302/timetout", { cert: false, timeout: 1000 })
    .then((res) => console.log(res) || res),
]);
console.log(res.reqbd);
console.log(res1.reqbd);
console.log(res2.reqbd);
await kit.sleep(5000);
console.log(
  "method,query,body,options,headers示例==========================================="
);
const json = { foo: "hello" };
[res, res1, res2] = await Promise.all([
  res
    .req("/test?a=1&a=2&b=宝贝 post", { json })
    .then((res) => console.log(res) || res),
  res1
    .req("/test?a=1&a=2&b=宝贝 post", { cert: false, timeout: 4000, json })
    .then((res) => console.log(res) || res),
  res2
    .req("/test?a=1&a=2&b=宝贝 post", { cert: false, timeout: 1000, json })
    .then((res) => console.log(res) || res),
]);
await kit.sleep(3000);
console.log("快速完全重复请求示例===========================================");
res.req().then((res) => console.log(res) || res);
res1.req().then((res) => console.log(res) || res);
res2.req().then((res) => console.log(res) || res);

5.redis

测试文件路径:./test/t-redis.js

6.pgsql

7.诸多使用的工具函数

测试文件路径:./test/t-basic.js ./test/t-codec.js

旧版文档,server相关内容,若新文档没来得及更新,可以先对付看着,有条件建议直接看源码

1.初识:先使用预设的路由default_routes,涵盖了常见使用示例,便于了解

import kit from "@ghini/kit/dev";
kit.cs();
// http1.1服务器
kit.hs(3001);
// http2tls服务器,兼容1.1
const server = kit.h2s(3002);
// 默认路由为空,但有全局404错误处理
console.log(server.routes);
// 这些是预定义的路由,可以尝试一一去访问,体会其效果
server.routes=kit.default_routes();
// function default_routes() {
//   return [
//     ["/", "*", "*", hd_hello.bind("Ghini"), undefined, {}],
//     [/^\/gold/, "*", "*", hd_hello.bind("RegExp"), undefined, {}],
//     ["/gold", "*", "*", hd_default, undefined, {}],
//     ["/data", "POST", "*", hd_data, undefined, {}],
//     ["/error", "*", "*", hd_error, undefined, {}],
//     ["/stream", "*", "*", hd_stream, undefined, {}],
//     ["/countdata", "*", "*", (g) => g.end(g.body), hd_countdata, {}],
//   ];
// }
console.log(server.routes);

2.进阶:拥有灵活强大的添加路由能力,尝试添加和覆写route

server.addr(/^\/gold/, (gold) => gold.raw("cover"));
server.addr("/data", "post", (gold) => gold.json(gold));
server.addr(/any/, (gold) => {
  gold.respond({
    "content-type": "text/plain;charset=UTF-8",
    "set-cookie":
      "name=ghini;max-age=3600;path=/;httponly;secure;samesite=strict",
  });
  gold.write("你可以使用任何带有any的url访问这个路由\n");
  gold.end("但不包括?后面的参数,其属于param");
});
// 第一个函数是handle_onend,第二个函数(很少用)是handle_ondata(需要传body,多一点效果明显)
server.addr(
  "/handle_ondata",
  (g) => g.end(g.body),
  (g, chunk, chunks) => {
    // 响应头一定是在body前返回的,如果直接write会默认给响应头
    // gold.respond方法做过优化,不会重复给响应头
    g.respond({
      "content-type": "text/plain;charset=UTF-8",
    });
    console.log(chunk, chunks.length);
    // 这里我们尝试改掉原来的chunks.push(chunk); 会影响gold.body的生成
    // chunks.push(chunk);
    chunks.push(Buffer.from(chunks.length+','));
    g.write(`data: ${chunks.length}\n`);
  }
);
console.log(server.routes);

3.自定义错误处理

server._404 = undefined; //虽然能去掉,但后台会报错
server._404 = () => {}; //正确不报错的去404提示
server._404 = (g) => {
  g.err("404 not found , 自定义的404响应", 404);
};

4.方便的数据获取,已对主要类型进行健全的自动化处理

// 用postman之类工具,对/data进行一些测试,比如[/post](https://localhost:3002/data?a=123&中文=你好),对body的json x-www-form-urlencoded form-data的主流类型都进行了支持,轻松一键获取数据.
// 我们使用最复杂的情况,form-data指定key携带多文件,和空key多文件
server.addr("/data",'post', (gold) => {
  gold.respond({ "content-type": "text/plain;charset=UTF-8" });
  gold.write(JSON.stringify(gold.param)+'\n');
  gold.end(JSON.stringify(gold.data,0,2));
});

可以看到诸如此类的数据,使用gold.param和gold.data直接调用

{"a":"123","中文":"你好"}
{
  "vk_swiftshader_icd.json": {
    "filename": "vk_swiftshader_icd.json",
    "content": "{\"file_format_version\": \"1.0.0\", \"ICD\": {\"library_path\": \".\\\\vk_swiftshader.dll\", \"api_version\": \"1.0.5\"}}",
    "contentType": "application/json"
  },
  "Squirrel-UpdateSelf.log": {
    "filename": "Squirrel-UpdateSelf.log",
    "content": "[15/12/24 09:23:05] info: Program: Starting Squirrel Updater: --updateSelf=C:\\Users\\pznfo\\AppData\\Local\\SquirrelTemp\\Update.exe\r\n[15/12/24 09:23:05] info: Program: About to wait for parent PID 46400\r\n[15/12/24 09:23:07] info: Program: Finished Squirrel Updater",
    "contentType": "text/plain"
  },
  "usekey": [
    {
      "filename": "profile.json",
      "content": "{\n  \"name\": \"Postman\",\n  \"company\": \"Postman\",\n  \"installationOptions\": {}\n}",
      "contentType": "application/json"
    },
    {
      "filename": "icon.png",
      "content": "�PNG\r\n\u001a\n+00:00���:\u0000\u0000\u0000%tEXtdate:modify\u0000IEND�B`�",
      "contentType": "image/png"
    }
  ],
  "ok": "good"
}