A small, local-first web client for the OpenAI Responses API, designed to run on Vercel or locally with Node.js. Conversations, drafts, settings and file copies live in your browser; a small Express backend handles authenticated API requests.
Noxi is an independent project and is not an official OpenAI product.
- Stream responses, stop generation, edit messages and regenerate replies.
- Read Markdown, code blocks, tables and web citations; copy or download responses.
- Attach documents and images, preview images and download files generated by tools.
- Select a model and adjust its supported reasoning, verbosity and temperature controls.
- Set instructions, additional instruction blocks, output limits, text or JSON output, and context strategy.
- Enable Web Search, Code Interpreter and Image Generation with cost confirmations.
- Search local history, import conversations and export JSON backups, Markdown, plain text or Word.
- Use a responsive Material 3 inspired interface with light/dark themes and adjustable text size.
There are no accounts, remote conversation database, cloud sync or analytics. A shared access key protects the installation; it is not a multiuser identity system.
Requirements: Node.js 24.x, npm, a modern browser with IndexedDB, and an OpenAI API key with access to the models you choose. API usage is billed to the owner of that key.
npm ciCopy .env.example to .env and set PASS_KEY to a strong, unique access key. Set OPENAI_API_KEY to your API key. Do not commit .env or put either key in browser code.
npm run build
npm startOpen localhost:3000 and sign in with PASS_KEY. npm run dev also starts the local server; it does not provide hot reload. The server listens on all interfaces, so use appropriate network access controls on a shared network.
Without an API key, local organization, settings, backups and Word export still work. PASS_KEY is required even locally. The browser interface requires the running server; local-first does not mean fully offline.
| Variable | Purpose / default |
|---|---|
OPENAI_API_KEY |
Server-side OpenAI credential, required for model requests and remote files. |
PASS_KEY |
Required shared access key. Also signs the seven-day session cookie. Rotating it invalidates existing sessions. |
OPENAI_MODEL |
Initial model for new conversations; defaults to gpt-5.6-terra. |
OPENAI_MODEL_OPTIONS |
Optional comma-separated catalog IDs shown in the picker. Featured entries and the default model remain available. This is a display filter, not an authorization allowlist. |
OPENAI_DEVELOPER_MESSAGE |
Fallback instruction when a conversation has no custom instructions. |
DEFAULT_MAX_OUTPUT_TOKENS |
Initial output budget, 4096, clamped to the model limit. |
DEFAULT_CONTEXT_STRATEGY |
all, window or last_turn; default all. |
DEFAULT_CONTEXT_WINDOW_SIZE |
Number of messages for window; default 10, range 1–100. |
DEFAULT_TEMPERATURE |
Initial temperature, 1; sent only for compatible models. |
MAX_ATTACHMENTS_PER_MESSAGE |
Default 8; may be lowered to 1–8. |
MAX_UPLOAD_MB |
Per-file limit in MiB; default 4, may be lowered. |
PORT |
Local server port, 3000; not needed on Vercel. |
Defaults apply to new conversations. Existing conversations retain their settings. Invalid or incompatible settings are normalized against the catalog.
- When ready to publish, place this project in your own Git repository and import it into Vercel, or deploy the project directory with the Vercel CLI.
- Use the project root, Other as the framework preset, Node.js 24.x,
npm cias the install command andnpm run buildas the build command. Keep the output-directory override disabled; this is an Express function with bundled static assets, not a static-only export. - Add
OPENAI_API_KEYand a strongPASS_KEYunder environment variables. Add any optional defaults from the table. Configure each intended environment, including Preview if you use it. - Deploy. Environment changes require a new deployment. Open the deployed URL, sign in and check a short response before enabling paid tools.
api/index.js exports the Express app. vercel.json routes requests through it, bundles public/**, enables Fluid Compute and configures a 300-second function duration with cancellation support. npm run build checks JavaScript syntax, validates local asset references and copies the installed Markdown renderer into public/vendor/; the interface does not require a CDN. No persistent server filesystem or database is needed.
The project pins a supported Vercel Node.js version. Function timeouts, payload limits and availability also depend on Vercel's current limits and your plan. Test long generations and large outputs on your own deployment. Keep the access key private; anyone who knows it can make requests using the installation's API key.
Use a stable deployment domain for daily work. Browser storage is scoped to the origin: localhost, a Preview URL and a production domain have separate histories. Export a JSON backup before changing domains.
public/core/model-catalog.js is the manual source of truth for model IDs, labels, groups, supported reasoning levels, verbosity, temperature, image/file inputs, tools, output limits and optional cost estimates. The browser builds the picker from it; server request validation and parameter construction use the same catalog.
The catalog contains exactly six models, in this order:
| Group | Model | Request ID |
|---|---|---|
| Recommended | GPT-5.6 Terra (default) | gpt-5.6-terra |
| Recommended | GPT-5.6 Luna | gpt-5.6-luna |
| Recommended | GPT-5.4 mini | gpt-5.4-mini-2026-03-17 |
| Other models | GPT-6 Astra | gpt-6-astra |
| Other models | GPT-6 Sol | gpt-6-sol |
| Other models | GPT-6 Luna | gpt-6-luna |
Availability depends on your OpenAI account; Noxi assumes no incentive enrollment or usage tier. Noxi never queries /v1/models automatically. All six support image/file inputs, verbosity, the application's three tools and 128000 output tokens. Reasoning efforts are none, low, medium, high, xhigh, max, except Astra excludes none and mini excludes max. Temperature is omitted from requests.
To add a model, copy an entry and verify its capabilities against the official model documentation:
{
id: 'your-model-id',
name: 'Display name',
group: 'Other models',
reasoning: [], // supported effort strings; empty means no reasoning control
verbosity: false,
temperature: true,
vision: true,
files: true,
tools: ['web_search'], // only verified, compatible tools
maxOutput: 32768,
}The example illustrates the schema, not a real model. The first entry is the default. featured: true keeps an entry visible when OPENAI_MODEL_OPTIONS filters the picker. Remove an entry to retire a model; saved settings using retired or unknown IDs fall back to Terra on load/import. The legacy gpt-5.4-mini alias maps to gpt-5.4-mini-2026-03-17; incompatible efforts/tools are normalized. Historical messages and their model IDs remain unchanged. Export important conversations before changing the catalog.
Optional pricing.rates contains input, cached input and output USD rates per million tokens. Optional pricing.longContext declares the threshold and multipliers. Rates verified on October 5, 2026 against official pricing and the model documentation: input/cached input/output USD per million are Terra 2/0.2/12, GPT-5.6 Luna 0.2/0.02/1.2, mini 0.75/0.075/4.5, Astra 10/1/50, GPT-6 Sol 2/0.2/10 and GPT-6 Luna 0.1/0.01/0.5. GPT-5.6 and GPT-6 requests with more than 272000 input tokens multiply input/cache rates by 2 and output rates by 1.5 for the entire request; mini has no such surcharge. Estimates are reference values, exclude tool charges and may become outdated; consult OpenAI billing for actual charges. Omit pricing to show token counts without a cost estimate.
public/core/models.js normalizes settings and selects context. all sends the usable history, window sends the last N usable messages, and last_turn sends the last user message. Noxi resends the selected context on each request and uses store: false; it does not depend on remote conversation state. Streaming uses the OpenAI Responses streaming API, translated by the server into a small newline-delimited event protocol.
Tools start off. Choose them in Settings → Tools. Enabled tools are available to the model; the model decides whether to use them.
| Tool | Purpose | Confirmation |
|---|---|---|
| Web Search | Search the web and display source links. | Every request, including regeneration. The server also rejects requests without confirmation. |
| Code Interpreter | Run code, analyze data and create downloadable files. | When enabled. |
| Image Generation | Generate or edit images and save returned images locally. | When enabled. |
Tools may incur additional charges beyond token usage. Turning a tool off prevents its inclusion in later requests. Stopping a response cancels the local request and signals cancellation upstream; it does not reverse usage already incurred.
Attach files with +, drag and drop, or paste images into the composer. The accepted extensions are listed in public/core/files.js; provider acceptance can vary by model and tool. Files stay in IndexedDB until needed for a request, then the backend uploads them to OpenAI. Uploads have a requested 24-hour expiry and signed references that are renewed from local copies when needed. Settings → Advanced settings → Clean up remote files deletes referenced uploads for the current conversation while keeping local copies.
Returned images and generated files are copied into browser storage and can be downloaded again after reloading. Remote code containers are temporary; a failed or oversized download may leave a file entry without a local copy. Deleting a conversation removes its local files; it does not perform remote cleanup. Clean up remote files before deleting a conversation if needed.
History → Import accepts Noxi JSON backups, compatible conversation JSON, Markdown and plain text. JSON imports create new IDs instead of overwriting conversations. Export offers a complete JSON backup of the current conversation and text-based formats; History → Export all backs up all conversations and files. Backups omit API credentials and signed upload references. Existing IndexedDB and versioned backup identifiers are preserved for compatibility.
Word export is generated by the backend without calling OpenAI. It receives the conversation text transiently and creates a basic paragraph document; it does not reproduce rendered Markdown layout or embed attachments. JSON is the format to use for restoration with file contents.
Local storage is not encrypted by Noxi. Anyone with access to your browser profile can potentially read it. Clearing site data, using temporary browser sessions or storage eviction can remove history. Noxi requests persistent storage, but browser support and permission vary. Keep backups outside the browser.
Messages, selected context, instructions and relevant attachments leave the browser when you send a request. They pass through your deployment to OpenAI. store: false does not promise zero retention or override provider policies. The deployment provider may retain request metadata under its own policies. Noxi adds no telemetry and does not enable OpenAI data sharing.
Current application limits:
- 4 MiB per uploaded file, 8 attachments per message and 32 files across the selected request context.
- 4 MiB JSON request body; reduce context or output budgets for large conversations.
- 32 MiB per downloaded Code Interpreter artifact and a 48 MiB maximum local event line; hosting limits may be lower.
- 150 MiB per imported backup and 1–1000 conversations per JSON import.
- 500,000 characters for Word export; text-only output.
- One writable tab per origin where the browser supports Web Locks. Close the first tab and reload the second to switch.
There is no automatic synchronization, background execution or resumable generation after the page closes. Interrupted output is retained when it has been saved. Model access, provider limits and deployment timeouts can interrupt requests.
api/index.js Vercel function entry
server.js Express setup and local entry
middleware/auth.js Shared-key session protection
routes/api.js Config, files, responses and Word export
services/ Validation, signed file references, stream adapter
public/index.html Conversation workspace and dialogs
public/app.js Workspace state and event coordination
public/core/ Catalog, storage, backups, rendering and API helpers
public/{tokens,styles,conversation,login}.css
Design roles, layout and content styles
scripts/build.mjs Syntax and asset checks, local Markdown bundle
tests/ Core, HTTP and browser regression tests
npm test
npm run build
npm run lint
npm exec playwright install chromium
npm run test:e2eThe browser suite uses mocked model responses and uploads; it does not spend API credits. Core tests cover persistence, backup compatibility, stream parsing, tool confirmation and server boundaries. Playwright and fake-indexeddb are development-only dependencies; Prettier checks formatting. A real OpenAI account and an actual Vercel deployment are needed to verify provider access and hosting behavior end to end.
Noxi started as a lightweight personal OpenAI API client, partly to make practical use of optional data-sharing incentives when available. It grew into a broader local-first interface for models, tools, files and persistent browser conversations. Eligibility and terms are controlled by OpenAI and may change; Noxi never enables data sharing automatically.