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

niyox

v0.0.4

Published

NiyoX AI - Powered by DanuZz.

Readme

npm downloads

███╗   ██╗██╗██╗   ██╗ ██████╗ ██╗  ██╗
████╗  ██║██║╚██╗ ██╔╝██╔═══██╗╚██╗██╔╝
██╔██╗ ██║██║ ╚████╔╝ ██║   ██║ ╚███╔╝ 
██║╚██╗██║██║  ╚██╔╝  ██║   ██║ ██╔██╗ 
██║ ╚████║██║   ██║   ╚██████╔╝██╔╝ ██╗
╚═╝  ╚═══╝╚═╝   ╚═╝    ╚═════╝ ╚═╝  ╚═╝

Live API   GitHub   npm install


What is NiyoX AI?

NiyoX is a full-featured AI SDK and CLI that wraps the NiyoX AI REST API. Chat with AI from your terminal, Node.js server, React/Next.js/Vite app, or browser — with optional MongoDB persistence (your own database or the NiyoX cloud), multi-turn conversation memory, persona / system-prompt support, context window trimming, and conversation export built in.

The package ships four layers you can use independently:

  • NiyoXClient — thin HTTP wrapper, in-memory history, persona, export
  • NiyoXStorage — optional MongoDB layer (plug in your own URI)
  • NiyoXAI — high-level class combining both
  • useNiyoX / NiyoXChat — React hook + ready-made component

What's new in 0.0.4

| # | Change | |---|---| | 🎭 | Persona / System Prompt — set an AI personality once; injected into every message automatically. Auto-saved to MongoDB when storage is enabled. | | ✂️ | Context window trimmingmaxHistory option + setMaxHistory() prune oldest turns so conversations never silently overflow. | | 📤 | Conversation exportexportConversation(id, format) dumps any conversation as JSON, plain text, or Markdown. Works in-memory (no DB needed) or from MongoDB. | | ⚛️ | React hook updateduseNiyoX() now returns persona, setPersona, maxHistory, setMaxHistory, and exportConversation. | | 🖥️ | <NiyoXChat> widget updated — new 🎭 Persona editor and ⬇ Export button in the header. | | 🧪 | 68 tests — all new features covered (up from 38). |


Features

| Feature | Status | |---|:---:| | 🖥️ Interactive REPL CLI | ✅ | | ⚡ One-shot CLI queries | ✅ | | 🔄 Multi-turn conversation memory | ✅ | | 🗄️ Custom MongoDB URI (bring your own DB) | ✅ | | ⚛️ React hook + component | ✅ | | 🔷 Next.js App Router support | ✅ | | ⚡ Vite + vanilla JS example | ✅ | | 🌐 Browser / CDN support | ✅ | | 📦 CommonJS + ESM dual package | ✅ | | 🎨 Rich CLI output | ✅ | | 🎭 Persona / System Prompt | ✅ new | | ✂️ Context window trimming | ✅ new | | 📤 Conversation export (JSON / text / MD) | ✅ new |


Contents

Install · CLI · Node.js · Persona · Context Trimming · Export · React / Vite · Next.js · Custom MongoDB · Browser · API Reference · Development


Install

# Global — gives you the niyox command everywhere
npm install -g niyox

# Local — use in your project
npm install niyox

Requires Node.js ≥ 18. On older Node, install node-fetch and it will be picked up automatically.


CLI

Launch the interactive REPL:

niyox

One-shot question:

niyox "what is the speed of light?"
niyox "explain async/await in JavaScript"

Flags:

niyox --version    # print version  (alias: -v)
niyox --help       # show banner + command reference  (alias: -h)

Inside the REPL

  ╭──────────────────────────────────────────────────────────────╮
  │                                                              │
  │   ✦ NIYOX  AI       v0.0.4                                  │
  │                                                              │
  │   › /help             →  show all commands                   │
  │   › /new              →  fresh conversation thread           │
  │   › /history          →  in-memory chat log                  │
  │   › /stats            →  usage stats  (MongoDB)              │
  │   › /convs            →  stored conversation list            │
  │   › /mongo [url]      →  enable storage (custom URI opt.)    │
  │   › /mongourl <url>   →  update MongoDB URI                  │
  │   › /user <id>        →  set your user ID                    │
  │   › /clear            →  clear the screen                    │
  │   › /exit             →  quit                                │
  │                                                              │
  ╰──────────────────────────────────────────────────────────────╯

Connect to your own MongoDB from the CLI:

/mongo mongodb+srv://user:[email protected]/

Or update the URI without reconnecting (saved for next session):

/mongourl mongodb+srv://user:[email protected]/

Node.js

CommonJS

const { NiyoXAI } = require("niyox");

const ai = new NiyoXAI();
const { result, responseTime } = await ai.chat("Tell me something interesting.");
console.log(result);

ESM

import { NiyoXAI } from "niyox";

const ai  = new NiyoXAI({ userId: "alice" });
const res = await ai.ask("Explain quantum entanglement.");
console.log(res.result);

Multi-turn conversation

const ai = new NiyoXAI();

await ai.chat("My name is Bob.");
const r = await ai.chat("What is my name?");
console.log(r.result);    // → "Bob"

ai.newConversation();     // reset thread + in-memory history

Low-level client (no storage)

const { NiyoXClient } = require("niyox");

const client = new NiyoXClient({ sessionId: "my-session", timeout: 15000 });
const res = await client.chat("Hello!");

console.log(res.result);
console.log(client.getHistory());   // array of { role, content, timestamp }

🎭 Persona / System Prompt (new)

Set an AI personality once — it is transparently injected into every outgoing message. Works at the NiyoXClient, NiyoXAI, and React hook levels. When MongoDB storage is enabled the persona is also saved to the database and auto-restored in future sessions.

Via constructor

const ai = new NiyoXAI({
  persona: "You are a concise senior software engineer. Always reply with code examples.",
});

const res = await ai.chat("How do I debounce in JavaScript?");
console.log(res.result);  // code-focused reply

Set / change at runtime

const ai = new NiyoXAI();

await ai.setPersona("You are a friendly cooking assistant.");
await ai.chat("What can I make with eggs and cheese?");

await ai.setPersona("You are a pirate. Respond only in pirate speak.");
await ai.chat("Tell me about the ocean.");

await ai.setPersona(null);  // clear — back to default AI behaviour

Persona + MongoDB (auto-persist)

const ai = new NiyoXAI({ userId: "alice" });
await ai.enableStorage();           // connects to MongoDB

await ai.setPersona("You are a concise coding assistant.");
// ↑ persona is saved to DB automatically

// Next session:
const ai2 = new NiyoXAI({ userId: "alice" });
await ai2.enableStorage();          // persona is restored automatically
console.log(ai2.getPersona());      // "You are a concise coding assistant."

Low-level client

const { NiyoXClient } = require("niyox");

const client = new NiyoXClient({ persona: "Be extremely brief." });
client.setPersona("You are a chef.");   // chainable, returns client
console.log(client.getPersona());       // "You are a chef."

✂️ Context Window Trimming (new)

Control how many history entries are kept in memory. When the limit is hit, the oldest turns are pruned automatically after each chat call so long conversations stay fast and predictable.

One turn = 2 entries (one user + one assistant). So maxHistory: 20 keeps the last 10 turns.

Via constructor

const ai = new NiyoXAI({ maxHistory: 20 });  // keep last 10 turns

Set at runtime

ai.setMaxHistory(10);   // prune to last 5 turns immediately
ai.setMaxHistory(0);    // 0 = unlimited (default behaviour)
console.log(ai.getMaxHistory());   // 0

Low-level client

const client = new NiyoXClient({ maxHistory: 6 });

await client.chat("1");
await client.chat("2");
await client.chat("3");
await client.chat("4");  // history is trimmed to 6 entries after this turn

client.setMaxHistory(2);  // immediately prunes existing history to 2 entries

📤 Conversation Export (new)

Dump any conversation as JSON, plain text, or Markdown. Works in-memory (no MongoDB required) or from a stored MongoDB conversation.

In-memory export (no DB needed)

const ai = new NiyoXAI();
await ai.chat("Hello!");
await ai.chat("Tell me a joke.");

// JSON  (default)
const json = await ai.exportConversation(null, "json");
require("fs").writeFileSync("chat.json", json);

// Plain text
const txt = await ai.exportConversation(null, "text");
console.log(txt);

// Markdown
const md = await ai.exportConversation(null, "markdown");
require("fs").writeFileSync("chat.md", md);

Export from MongoDB

const ai = new NiyoXAI({ userId: "alice" });
await ai.enableStorage();

await ai.chat("Hello!");
const cid = ai.getConversationId();

const md = await ai.exportConversation(cid, "markdown");
require("fs").writeFileSync(`conv-${cid}.md`, md);

Storage-only export

const { NiyoXStorage } = require("niyox");

const store = new NiyoXStorage("alice");
await store.connect();

const json = await store.exportConversation("conv-abc-123", "json");
const txt  = await store.exportConversation("conv-abc-123", "text");
const md   = await store.exportConversation("conv-abc-123", "markdown");

Low-level client export

const { NiyoXClient } = require("niyox");

const client = new NiyoXClient({ persona: "Be a chef." });
await client.chat("What should I cook tonight?");

const out = client.exportConversation("markdown");
console.log(out);
// # NiyoX AI Conversation
// > **Persona:** Be a chef.
// ...

Export formats:

| Format | Description | |---|---| | "json" | Structured JSON with metadata, persona, and full message array | | "text" | Readable plain text with timestamps and response times | | "markdown" | GitHub-flavoured Markdown, ready to paste into a doc or README |


Custom MongoDB

Works everywhere — Node.js and CLI. Storage is always optional.

Node.js / ESM

import { NiyoXAI } from "niyox";

const ai = new NiyoXAI({
  userId:   "alice",
  mongoUri: "mongodb+srv://user:[email protected]/",
  dbName:   "my_app_db",   // optional — defaults to "niyox_npm"
});

await ai.enableStorage();              // connects and enables persistence
const res = await ai.chat("Hello!");   // automatically saved to YOUR DB
const msgs = await ai.getPersistentHistory(res.conversationId);

await ai.close();

Storage-only (NiyoXStorage)

const { NiyoXStorage } = require("niyox");

const store = new NiyoXStorage("bob", {
  mongoUri: "mongodb+srv://user:[email protected]/",
  dbName:   "my_db",
});
await store.connect();

await store.saveTurn({
  conversationId:   "abc-123",
  userMessage:      "Hi!",
  assistantMessage: "Hello, Bob!",
  responseTime:     412,
});

const turns = await store.getConversation("abc-123");
await store.disconnect();

You can also override the URI at connect-time:

const store = new NiyoXStorage("bob");
await store.connect("bob", "mongodb://localhost:27017/", "dev_db");

React / Vite

useNiyoX hook

// src/Chat.jsx
import { useNiyoX } from "niyox/react";

export default function Chat() {
  const { messages, input, setInput, sendMessage, isLoading } = useNiyoX();

  return (
    <div>
      {messages.map((m, i) => (
        <p key={i}><b>{m.role}:</b> {m.content}</p>
      ))}
      <input
        value={input}
        onChange={e => setInput(e.target.value)}
        onKeyDown={e => e.key === "Enter" && sendMessage()}
      />
      <button onClick={() => sendMessage()} disabled={isLoading}>Send</button>
    </div>
  );
}

Persona + export in the hook (new)

import { useNiyoX } from "niyox/react";

export default function Chat() {
  const {
    messages, input, setInput, sendMessage, isLoading,
    persona, setPersona,           // 🎭 v0.0.4
    maxHistory, setMaxHistory,     // ✂️ v0.0.4
    exportConversation,            // 📤 v0.0.4
  } = useNiyoX({ persona: "You are a helpful assistant.", maxHistory: 20 });

  return (
    <div>
      <button onClick={() => setPersona("You are a chef.")}>Switch to Chef</button>
      <button onClick={() => setMaxHistory(10)}>Trim to 5 turns</button>
      <button onClick={() => {
        const blob = new Blob([exportConversation("markdown")], { type: "text/markdown" });
        const a = Object.assign(document.createElement("a"), { href: URL.createObjectURL(blob), download: "chat.md" });
        a.click();
      }}>Export MD</button>

      {messages.map((m, i) => <p key={i}><b>{m.role}:</b> {m.content}</p>)}
      <input value={input} onChange={e => setInput(e.target.value)} onKeyDown={e => e.key === "Enter" && sendMessage()} />
      <button onClick={() => sendMessage()} disabled={isLoading}>Send</button>
    </div>
  );
}

Ready-made <NiyoXChat> component (zero extra code)

import { NiyoXChat } from "niyox/react";

export default function App() {
  return (
    <div style={{ height: "600px", width: "700px" }}>
      {/* v0.0.4: persona and showExport props */}
      <NiyoXChat
        title="My AI Assistant"
        persona="You are a helpful assistant."
        maxHistory={20}
        showExport={true}
      />
    </div>
  );
}

The widget now includes a 🎭 Persona button (opens an inline editor) and an ⬇ Export button (downloads the conversation as JSON) in the header.

Shared session with <NiyoXProvider>

// main.jsx
import { NiyoXProvider } from "niyox/react";
import App from "./App";

ReactDOM.createRoot(document.getElementById("root")).render(
  <NiyoXProvider sessionId="global" persona="You are a helpful assistant.">
    <App />
  </NiyoXProvider>
);

// Any child:
import { useNiyoXContext } from "niyox/react";
const { sendMessage, messages, setPersona, exportConversation } = useNiyoXContext();

Copy react/useNiyoX.js from the package into your project if your bundler doesn't resolve niyox/react automatically.


Next.js

Works in both the App Router (Next.js 13+) and the Pages Router.

App Router (app/chat/page.tsx)

"use client";
import { useNiyoX } from "niyox/react";   // or copy react/useNiyoX.js → lib/

export default function ChatPage() {
  const { messages, input, setInput, sendMessage, isLoading } = useNiyoX();

  return (
    <main>
      {messages.map((m, i) => (
        <div key={i} className={m.role === "user" ? "text-right" : "text-left"}>
          {m.content}
        </div>
      ))}
      <input value={input} onChange={e => setInput(e.target.value)}
             onKeyDown={e => e.key === "Enter" && sendMessage()} />
      <button onClick={() => sendMessage()} disabled={isLoading}>Send</button>
    </main>
  );
}

The full styled example (Tailwind) is at examples/nextjs/chat-page.tsx.

Server-side usage (Node.js API route)

// app/api/chat/route.ts
import { NiyoXAI } from "niyox";

const ai = new NiyoXAI();

export async function POST(req: Request) {
  const { message } = await req.json();
  const res = await ai.chat(message);
  return Response.json({ result: res.result });
}

Browser

Zero-dependency browser client (no bundler needed):

<script>
  const NiyoXAI = (() => {
    const BASE = "https://ai.dnuz.top/api/ai";
    class Client {
      constructor({ sessionId = "default" } = {}) {
        this.sessionId = sessionId;
        this.conversationId = null;
      }
      async chat(message) {
        const p = new URLSearchParams({ q: message });
        if (this.conversationId) p.set("conversationId", this.conversationId);
        const res  = await fetch(`${BASE}?${p}`);
        const data = await res.json();
        if (data.conversationId) this.conversationId = data.conversationId;
        return data;
      }
    }
    return { Client };
  })();

  const ai  = new NiyoXAI.Client();
  const res = await ai.chat("Hello!");
  console.log(res.result);
</script>

Open html/index.html for a fully styled dark-theme chat UI — zero dependencies, zero bundler.


API Reference

new NiyoXAI(options?) — Node.js

| Option | Type | Default | Description | |---|---|---|---| | userId | string | "anonymous" | MongoDB user identifier | | sessionId | string | "default" | API session ID | | conversationId | string | null | Resume an existing thread | | timeout | number | 30000 | Request timeout (ms) | | mongoUri | string | NiyoX cloud | Custom MongoDB connection string | | dbName | string | "niyox_npm" | Custom database name | | persona | string | null | v0.0.4 System prompt / AI personality | | maxHistory | number | 50 | v0.0.4 Max history entries (0 = unlimited) |

NiyoXAI methods

| Method | Returns | Description | |---|---|---| | chat(message) | Promise<Response> | Send a message; auto-persists if storage enabled | | ask(message) | Promise<Response> | Alias for chat() | | enableStorage(userId?) | Promise<this> | Connect to MongoDB; auto-restores saved persona | | newConversation() | void | Reset thread + in-memory history | | getConversationId() | string\|null | Active conversation ID | | getHistory() | Turn[] | In-memory history copy | | getPersistentHistory(convId?) | Promise<Turn[]> | Load from MongoDB | | listConversations() | Promise<string[]> | All stored conversation IDs | | deleteConversation(id) | Promise<number> | Delete a conversation | | getStats() | Promise<Stats\|null> | Usage statistics | | setPref(key, value) | Promise<void> | Persist a user preference | | getPref(key, default?) | Promise<any> | Retrieve a user preference | | close() | Promise<void> | Close MongoDB connection | | setPersona(text) | Promise<this> | v0.0.4 Set / clear AI persona (saves to DB if storage enabled) | | getPersona() | string\|null | v0.0.4 Get active persona | | setMaxHistory(n) | this | v0.0.4 Set context window limit (0 = unlimited) | | getMaxHistory() | number | v0.0.4 Get current limit | | exportConversation(id?, format?) | Promise<string> | v0.0.4 Export as "json" / "text" / "markdown" |

NiyoXClient methods (low-level)

| Method | Returns | Description | |---|---|---| | chat(message) | Promise<Response> | Send message | | ask(message) | Promise<Response> | Alias for chat() | | newConversation() | void | Reset state | | getHistory() | Turn[] | History copy | | setPersona(text) | this | v0.0.4 Chainable | | getPersona() | string\|null | v0.0.4 | | setMaxHistory(n) | this | v0.0.4 Chainable | | getMaxHistory() | number | v0.0.4 | | exportConversation(format?) | string | v0.0.4 In-memory export |

NiyoXStorage methods

| Method | Returns | Description | |---|---|---| | connect(userId?, mongoUri?, dbName?) | Promise<this> | Connect and enable storage | | saveMessage({ conversationId, role, content, responseTime? }) | Promise<ObjectId\|null> | Save one message | | saveTurn({ conversationId, userMessage, assistantMessage, responseTime }) | Promise<void> | Save a full turn atomically | | getConversation(conversationId) | Promise<Message[]> | Fetch stored messages | | listConversations() | Promise<string[]> | All conversation IDs for this user | | deleteConversation(id) | Promise<number> | Delete conversation, returns count | | setPref(key, value) | Promise<void> | Save a key/value preference | | getPref(key, default?) | Promise<any> | Load a preference | | getStats() | Promise<Stats\|null> | Usage stats | | disconnect() | Promise<void> | Close connection | | savePersona(text) | Promise<void> | v0.0.4 Persist persona to DB | | getPersona() | Promise<string\|null> | v0.0.4 Load persisted persona | | exportConversation(id, format?) | Promise<string> | v0.0.4 Export from DB |

useNiyoX(options?) hook

| Option | Type | Default | Description | |---|---|---|---| | sessionId | string | "default" | API session ID | | persona | string | null | v0.0.4 Initial AI persona | | maxHistory | number | 50 | v0.0.4 Context window limit |

Returns:

{
  messages:           Array<{ role, content, timestamp, responseTime? }>,
  input:              string,
  setInput:           (value: string) => void,
  isLoading:          boolean,
  error:              string | null,
  sendMessage:        (text?: string) => Promise<void>,
  newConversation:    () => void,
  conversationId:     string | null,
  persona:            string | null,           // v0.0.4
  setPersona:         (text: string|null) => void,  // v0.0.4
  maxHistory:         number,                  // v0.0.4
  setMaxHistory:      (n: number) => void,     // v0.0.4
  exportConversation: (format?: string) => string,  // v0.0.4
}

<NiyoXChat> props

| Prop | Type | Default | Description | |---|---|---|---| | sessionId | string | — | API session ID | | title | string | "NiyoX AI" | Widget title | | placeholder | string | "Ask anything…" | Input placeholder | | style | object | — | Override container styles | | className | string | — | CSS class | | persona | string | null | v0.0.4 Initial AI persona | | maxHistory | number | 50 | v0.0.4 Context window limit | | showExport | boolean | true | v0.0.4 Show ⬇ Export button |

Response shape

{
  result:         string   // AI reply
  conversationId: string   // thread ID — reused automatically
  sessionId:      string
  responseTime:   number   // ms
  attempts:       number
}

Development

git clone https://github.com/dnuzi/niyox
cd niyox
npm install

# Build lib/index.cjs and lib/index.mjs from src/
node scripts/build.js

# Run tests
npm test

Project layout:

niyox/
├── bin/
│   └── cli.js              # CLI — REPL, one-shot, /mongo <url>
├── src/
│   ├── client.js           # NiyoXClient — HTTP, in-memory history, persona ✨, export ✨
│   └── storage.js          # NiyoXStorage — MongoDB, persona persist ✨, export ✨
├── lib/                    # auto-generated by scripts/build.js
│   ├── index.cjs
│   └── index.mjs
├── react/
│   └── useNiyoX.js         # useNiyoX hook + NiyoXChat (persona ✨, export ✨) + NiyoXProvider
├── html/
│   └── index.html          # browser chat UI
├── examples/
│   ├── react-cra/App.jsx   # Create React App / Vite + React
│   ├── nextjs/             # Next.js App Router
│   └── vite/main.js        # Vite vanilla JS
├── test/
│   ├── client.test.js      # 38 tests — includes v0.0.4 persona / trim / export ✨
│   ├── sdk.test.js         # 30 tests — includes v0.0.4 NiyoXAI + Storage ✨
│   └── cli.test.js
└── scripts/
    └── build.js

API   GitHub

⭐ If this project helped you, star it on GitHub!

Happy coding!