v0.2.1
Documentation
Home GitHub
Getting Started

Introduction to Flux

Flux is a local-first, AI-powered desktop API client built on Tauri 2.0 and React 18. It stores everything on disk, uses under 30 MB RAM, and ships zero Electron. Collections are plain YAML you can commit to Git.

Something unclear, or missing? Ask in Discussions — questions about the docs are the fastest way to get them fixed. Something broken goes in Issues, and the contributing guide covers building Flux and opening a pull request.

Quick Start
Send your first request in under 60 seconds.
Installation
Download and install Flux on Windows, macOS, or Linux.
Collections
Organize requests in YAML collections and share them via Git.
AI Features
Generate tests, debug errors, and autocomplete with Claude.

Why Flux?

Feature Flux Others
Memory usage ~28 MB 200–400 MB (Electron)
Storage format Plain YAML, Git-friendly Proprietary JSON / cloud-only
AI integration Free tier included, or BYOK for unlimited Subscription or none
gRPC support Proto files + server reflection Varies
Offline first Fully offline Requires cloud sync
Protocols HTTP, gRPC, WebSocket, SSE Usually HTTP only
Free tier, or bring your own key
The beta includes 100 AI actions a month, relayed through a Flux proxy that applies the quota and picks the model. Add your own Claude API key for unlimited use and full model choice: it is never stored on any server, it lives only on your device, and calls then go straight to Anthropic.

Tech stack

  • Frontend: React 18, TypeScript, Vite, Tailwind CSS v4, Zustand, Radix UI
  • Backend: Rust + Tauri 2.0, reqwest (HTTP engine), rusqlite (history)
  • Code editor: Monaco Editor with local workers, no CDN dependency
  • AI: Anthropic Claude API, metered free tier or BYOK with Sonnet, Opus and Haiku selectable
Getting Started

Installation

Flux ships as a single native binary, no runtime, no Electron, no Node.js required on the host machine.

Download

Go to the latest release on GitHub and download the installer for your platform.

Platform File Notes
Windows Flux_x64-setup.exe x64 NSIS installer
macOS (Apple Silicon) Flux_aarch64.dmg M1/M2/M3
macOS (Intel) Flux_x64.dmg Intel Macs
Linux Flux_amd64.deb Debian/Ubuntu
macOS Gatekeeper
If macOS blocks the app, go to System Settings → Privacy & Security and click "Open Anyway" after the first failed launch.

Account

A free account is required to sync collections. Sign up with your email or with GitHub OAuth directly inside the app on first launch. No credit card needed.

System requirements

  • Windows: Windows 10 / 11 (x64)
  • macOS: 11.0+ (Big Sur or later)
  • Linux: Ubuntu 20.04+ or equivalent (GTK 3 required)
  • RAM: 30 MB typical, 60 MB peak
  • Disk: ~9 MB installer
Getting Started

Quick Start

Send your first request and save it to a collection in under two minutes.

An account is optional

Use Flux without an account on the sign-in screen goes straight in, and the choice is remembered. Everything local works without one:

  • Requests, collections, environments and variables
  • Pre/post-request scripts, assertions and the Collection Runner
  • The mock server, load tests, gRPC, WebSocket and SSE
  • The CLI runner, which never needed an account

An account adds cloud sync and the free AI tier, which is metered per account and is why it needs one. The AI also works without an account if you bring your own Claude API key, in Settings → AI & Claude. You can sign in at any time from the avatar menu or from Settings, and nothing on this machine is lost when you do.

1
Open the Request Builder
Click the Requests icon (top of the NavRail on the left). The main panel shows the URL bar, method selector, and tab strip.
2
Enter a URL and hit Send
Type https://jsonplaceholder.typicode.com/todos/1, select GET, then press Enter or click Send. The Response Panel on the right fills with the JSON response.
3
Save to a collection
Press the Save button (top-right of the request panel). Choose an existing collection or create a new one by typing a name. The request is saved as a YAML file on disk.
4
Generate tests with AI
After a response arrives, click Generate Tests in the Response Panel. Flux sends the response shape to Claude and inserts ready-to-run JavaScript tests in the Tests tab.
Command Palette
Press Ctrl + K to open the Command Palette. It searches across all collections and history in real time.
Release Notes

What's New

What changed in each release, and what you need to know before updating. The full history lives in CHANGELOG.md.

0.2.0

Your CI may start reporting failures it was hiding
An assertion whose left side was not recognised used to resolve to null, so anything.at.all == null passed against any response, and the CLI exited 0. Those assertions now fail with unknown path '…'. If a pipeline turns red after updating, it was green without checking anything. The error message names the path and the roots that are valid.

One assertion language everywhere

The Collection Runner, the Tests screen and the CLI each had their own evaluator, so the same assertion could pass in one and fail in another. They now share a single engine. Both spellings of a body path work, and so do both header forms:

json.token != null        // same as body.token != null
headers["Content-Type"]   // same as headers.content-type
duration < 500            // now works in all three

Failures also say what they got: expected status == 404, got 200. See Tests for the full syntax.

AI without an API key

Every signed-in account gets 100 AI actions a month, up to 20 a day, with nothing to configure. Free-tier prompts are relayed through a small Flux proxy, which is how the quota is applied at all; with your own key nothing is relayed and calls go straight from your machine to Anthropic. Privacy spells out what each mode sends.

Settings → AI & Claude shows what you have spent this month and today, and a toggle switches between the free tier and your own key without having to delete the key first. Hitting a limit says which one and when it resets. The model selector is disabled on the free tier, which runs on a fixed model, instead of accepting a choice that was silently ignored. See AI & Claude.

Pre and post-request scripts run in CI

The CLI embeds a JavaScript engine and the same pm shim the app uses. A collection that authenticates through a pre-request script now runs in CI instead of being skipped with a warning:

flux run collection.yaml // scripts execute, no longer skipped

pm.test() results count as assertions, so a failing Postman-style test fails the build, and console.log output appears under each request. See CLI Runner for what it still does not do.

A Content Security Policy for the webview

The webview shipped without one. Everything now loads from the app itself, the only outbound destination allowed from the frontend is your own Supabase project, and object-src, frame-ancestors and base-uri are locked down. unsafe-eval is kept on purpose: pre and post-request scripts run through new Function(), and without it the whole scripting feature would break in release builds only.

Fonts are served from the bundle instead of a third-party CDN. Flux no longer contacts fonts.bunny.net on launch, and typography works offline.

Collections carry the whole request

Saving a request used to keep only its method, URL, headers and body. Auth, query params, pre and post-response scripts, variable extractors, GraphQL queries and form bodies were dropped, and assertions were written out empty. All of it is saved and restored now, and the CLI honours it too, so a collection that works in the app works in CI.

Credentials stay out of your collection files
Saving a request whose auth holds a literal token now warns before writing it to disk, and offers to move it into the active environment as a masked {{VAR}} in one click. It matters because collections are meant to be committed, see GitHub Sync.

Switching requests no longer carries credentials over

Opening a request from a collection, replaying from History, or picking a result in the command palette kept the previously open request's auth, scripts and extractors. A bearer token set for one API could go out to a different host. All three reset the request first now.

Also in 0.2.0

  • Collections support folders nested at any depth, and every request keeps a stable id, so deleting or reordering no longer renumbers everything below it.
  • Collection description is no longer dropped on save.
  • The CLI runs auth (bearer, basic, API key, OAuth 2.0 client credentials), query params, form and GraphQL bodies. It reports what it cannot do instead of running a request that quietly differs.

0.1.7

QUERY method RFC 10008

Safe, idempotent and cacheable like GET, but the query travels in the request body instead of the URL. The first new general-purpose HTTP method since PATCH. Pick it from the method selector, see URL Bar & Method.

gRPC streaming

Server-streaming, client-streaming and bidirectional calls, with a live message log, per-message send, end-of-stream and cancel. Previously a streaming method could be selected but not invoked. See gRPC.

Import fixes worth knowing about

  • A cURL command with a body containing double quotes, which is most JSON, lost the body entirely and came in as GET. Re-import anything you brought in with Copy as cURL.
  • Flux could not re-import its own exported cURL snippets, because the URL was only found when it came first.
  • Variable extractor rules like $.items[*].id returned whole JSON objects instead of the field.
  • An assertion on a field that was absent failed == null, while an explicitly-null one passed.
Request Builder

URL Bar & Method

The URL bar is the primary entry point for every request. It supports environment variable interpolation, a method picker, and a one-click Send button.

Method selector

Click the method badge to the left of the URL field. Supported methods:

GETPOSTQUERYPUT PATCHDELETEHEAD OPTIONS

The QUERY method RFC 10008

QUERY is safe, idempotent and cacheable like GET, but the query travels in the request body instead of the URL. Use it for read-only calls whose parameters are too large or too structured to fit in a query string: a search with nested filters, a batch lookup by id, a GeoJSON polygon.

QUERY https://api.example.com/search
Content-Type: application/json

{
  "filters": { "status": "active", "tags": ["a", "b"] },
  "sort": "created_at"
}

The body works exactly as it does for POST, see Body. Because the method is safe, a server may cache the response and a client may retry it, which is the difference from sending the same payload as POST.

Check your server supports it
QUERY was standardised in June 2026, so support is still arriving. A server that does not know the method will usually answer 405 Method Not Allowed. Proxies and gateways in front of your API may reject it before it ever gets there.

Environment interpolation

Use {{variableName}} syntax anywhere in the URL. Active environment variables and global variables are resolved at send time.

https://{{baseUrl}}/api/users/{{userId}}

Keyboard shortcuts

Action Shortcut
Send request Enter (while URL focused)
Command palette Ctrl + K
New request tab Ctrl + T
Close tab Ctrl + W
Format body Shift + Alt + F
Toggle sidebar Ctrl + B
Go to History Ctrl + H
Go to Collections Ctrl + L
Go to Environments Ctrl + E
Request Builder

Params

Query parameters are managed in the Params tab. They are appended to the URL automatically.

Adding parameters

Click + Add param and fill in a key and value. Toggle the checkbox to include or exclude a parameter without deleting it. The URL bar updates live as you type.

Bulk edit

Switch to Bulk Edit mode to paste a raw query string directly:

page=1&limit=20&sort=createdAt&order=desc
Environment variables in params
Values support {{variable}} interpolation just like the URL field.
Request Builder

Headers

Add, remove, and toggle HTTP request headers. Smart autocomplete surfaces common header names and values as you type.

Common headers

Header Example value
Content-Type application/json
Authorization Bearer {{accessToken}}
Accept application/json
X-Request-ID {{$uuid}}

Header inheritance

Headers defined at the collection or folder level are automatically merged into every child request. A request-level header with the same name takes precedence.

AI smart autocomplete
When Smart Autocomplete is enabled in Settings → AI, Flux suggests header names and values based on your API context using Claude.
Request Builder

Auth

The Auth tab provides structured authentication configuration so you never have to manually compose Authorization headers.

Auth types

Type Description
None No authentication header added.
Bearer Token Adds Authorization: Bearer <token>. Supports {{variables}}.
Basic Auth Encodes username and password as Base64 in the Authorization header.
API Key Injects a key-value pair into headers or query params.
OAuth 2.0 Authorization code (opens a browser and captures the callback) and client credentials.
AWS Sig v4 Signs the request with AWS credentials for SigV4-protected services.
Store tokens in environments
Set your token as an environment variable (e.g., accessToken) and reference it as {{accessToken}} in the Bearer field. Switching environments automatically swaps the token.

Saving auth to a collection

Auth is stored with the request, so reopening it restores the whole configuration. Credential values should be {{VAR}} references rather than literals, because collection files are meant to be committed and synced.

If you save a request whose auth holds a literal secret, Flux stops and offers to fix it:

This credential would be written in plain text into the collection file.

Bearer token
[ Move to {{GET_USERS_TOKEN}} ]

Save anyway

Choosing Move to writes the value into the active environment, marks it as a secret so it is masked in the UI, and leaves the reference in the request. If there is no active environment it goes to the globals. Save anyway is there when you know what you are doing, for a throwaway local collection.

Auth in CI
The CLI runs Bearer, Basic, API key and OAuth 2.0 client credentials. Authorization code needs a browser, so it cannot work unattended, and AWS SigV4 is not supported there yet: the run fails with a message rather than sending an unsigned request.
Request Builder

Body

The Body tab opens when the selected method supports a request payload (POST, PUT, PATCH, etc.). Monaco Editor powers all text-based body types.

Body types

JSON Form URL-encoded Multipart Form XML GraphQL Binary Raw text

JSON

Full Monaco Editor with syntax highlighting, error detection, and inline linting. Press Shift + Alt + F to auto-format.

"name": "Alice",
"age":  30,
"admin": false

GraphQL

Split view with a Query editor and a Variables editor side by side. Both use Monaco with GraphQL language support.

query GetUser($id: ID!) {
  user(id: $id) {
    name
    email
  }
}

Form URL-encoded

Key-value table editor, identical to the Params tab. Encoded as application/x-www-form-urlencoded.

Multipart Form

Supports text fields and file uploads. Each part can be individually named and typed.

Binary

Upload any file from disk. The Content-Type header is inferred from the file extension.

AI body editing
Right-click inside the JSON body editor and select Edit with AI. Describe the change in plain English and Claude rewrites the body for you.
Request Builder

Pre-request Script

JavaScript that runs before each request is sent. Use it to compute dynamic values, set variables, or conditionally modify the request.

Available globals

Object Description
pm.environment.get(key) Read an environment or global variable
pm.environment.set(key, value) Write one back, available to this request and the ones after it
pm.variables Alias of pm.environment
pm.request.headers.upsert(key, value) Add or replace a header on the outgoing request. .add() does the same.
console.log Output appears in the Console tab
Scripts change headers and variables, not the whole request
A pre-request script can set headers and environment variables. The URL, method and body come from the request builder, so edit those there using {{variables}} for anything the script computes.

Example, sign a request

Compute the value in the script, then reference it from the header or body field:

const secret = pm.environment.get("apiSecret");
const nonce  = String(Date.now());

pm.environment.set("nonce", nonce);
pm.request.headers.upsert("X-Nonce", nonce);
pm.request.headers.upsert("Authorization", "Bearer " + secret);
Scripts do not run in the CLI
The CLI runner has no JavaScript engine, so pre and post-response scripts are skipped in CI. It prints a notice when a collection contains them. Anything a run in CI depends on should come from the request itself or from --env.
Request Builder

Post-response Script

JavaScript that runs after a response is received. Ideal for extracting values from responses and writing them to environment variables for use in subsequent requests.

Available globals

Object Description
pm.response.status Status code
pm.response.json() Parsed JSON body, or null when the body is not JSON
pm.response.text() Raw body as a string
pm.response.headers.get(name) One header, case-insensitive. .toObject() returns them all.
pm.response.responseTime Round trip in milliseconds
pm.environment.get / set Read and write environment variables. pm.variables is an alias.
pm.test(name, fn) A named check. It fails when the function throws.
pm.expect(value) Chai-style assertions: .to.equal, .to.eql, .to.include, .to.be.a, .to.be.ok, .to.be.null, .to.be.above, .to.be.below
console.log Output to the Console tab

Example, extract JWT after login

const data = pm.response.json();

if (data?.token) {
  pm.environment.set("accessToken", data.token);
  console.log("Token saved:", data.token.slice(0, 20) + "...");
}

pm.test("login returns a token", () => {
  pm.expect(data.token).to.be.a("string");
});
For a plain field, use the extractor instead
Pulling one value out of a response does not need a script: Extract does it with a JSONPath rule, and unlike scripts it also works in the CLI.
Request Builder

Extract

The Extract tab provides a no-code UI for pulling values from a response body and storing them in environment variables, no scripting required.

How it works

1
Define an extraction rule
Click + Add extraction. Choose the source type: JSON path, Header, or Cookie.
2
Enter the path
For JSON: use dot notation like data.user.id or bracket syntax items[0].id.
3
Name the target variable
The extracted value is written to the active environment under this name after each successful response.
Response Panel

Response Panel

The Response Panel occupies the right third of the main screen and shows everything Flux receives back from the server.

Status bar

At the top of the panel, three numbers are always visible after a request completes:

Metric Description
Status HTTP status code with color indicator, green (2xx), amber (3xx/4xx), red (5xx)
Time Total round-trip time in ms or seconds
Size Response body size in bytes / KB / MB

Tabs

Body Headers Cookies Tests Timeline Console
Response Panel

Body

The Body tab renders the response payload with automatic format detection and syntax highlighting.

View modes

Mode Description
Pretty Auto-formatted JSON, XML, or HTML with Monaco syntax highlighting. Read-only.
Raw Unformatted response bytes as-is.
Preview HTML responses rendered in an isolated webview.
Binary Hex dump for binary content types (images, PDFs, etc.).

Copy & Save

Click Copy to put the entire body on your clipboard. Click Save to file to write it to disk, useful for binary responses like file downloads.

Generate Tests from this response
Click Generate Tests (visible below the body when AI is configured). Claude analyzes the response shape and writes assertions that are immediately saved to the Tests tab.
Response Panel

Headers & Cookies

Inspect every header and cookie the server returned, with one-click copy for any value.

Headers tab

All response headers are shown in a searchable table. Click any row to copy the value. Common headers like Content-Type, Cache-Control, and X-Request-Id are highlighted.

Cookies tab

Cookies set by the response (via Set-Cookie) appear here with all attributes: name, value, domain, path, expiry, Secure, and HttpOnly. They are automatically stored in the Cookie Jar for subsequent requests.

Response Panel

Tests

One assertion per line, no scripting. Tests run automatically after each request and show pass / fail inline, and the same assertions run in the Collection Runner and in CI through the CLI.

Writing tests

An assertion is a path, an operator and a value:

status == 200
duration < 500
json.token != null
json.user.name == "ana"
headers["Content-Type"] == "application/json"
body contains "success"

Paths

Path Resolves to
status HTTP status code
duration Round trip in milliseconds
body The whole response body
json.a.b · body.a.b A field in the JSON body. The two spellings are interchangeable.
headers.name · headers["name"] A response header, case-insensitive. Both forms are equivalent.

Operators

==, !=, <, >, <=, >=, and contains for substring checks. === and !== are accepted as aliases.

Values are null, true, false, a number, or a quoted string. A numeric string in the response matches a number in the assertion, so json.id == 5 passes when the body has "id": "5".

Variables

{{VAR}} is interpolated in an assertion from the active environment and the global variables, the same as anywhere else:

json.token == "{{EXPECTED_TOKEN}}"
json.count == {{EXPECTED_COUNT}}
body contains "{{TENANT}}"

Interpolation happens after the operator has been read, so a variable whose value contains == cannot change how the line is parsed. A variable that is not defined is left as written, so the assertion fails and the message shows {{VAR}} rather than passing silently.

Reports and history show the assertion as you wrote it, with the {{VAR}} in place, so the value of a secret variable does not end up in a CI log or in the request history.

Absent fields

A field that is not in the response counts as null, so both of these hold when token is missing:

json.token == null        // passes
json.token != null        // fails
A path that is not one of the above is an error
An unrecognised path fails with unknown path '…' rather than resolving to null. Without that, a typo like dta.token == null would pass against every response and the test would look green while checking nothing.

Where assertions run

The same lines are evaluated by the same engine in three places: inline under the response, in the Collection Runner, and in the CLI. An assertion means the same thing in all three.

Need real logic?
Assertions are deliberately declarative. For anything that needs code, such as signing a payload, looping or conditionals, use a post-response script, which gives you the pm API. Scripts run in the app but not in the CLI.

AI-generated tests

Click Generate Tests in the Body tab. Flux sends the response schema to Claude, which returns a set of assertions in the syntax above, ready to run.

Test suite integration

Tests saved per-request are also visible and runnable from the Collection Runner and from the Tests screen in the NavRail.

Response Panel

Timeline

A waterfall view of the request lifecycle, broken into phases so you can identify exactly where time is spent.

Phases

Phase Description
DNS Lookup Time to resolve the hostname to an IP address
TCP Connect Time to establish the TCP connection
TLS Handshake Time to negotiate TLS (HTTPS only)
Time to First Byte Time from sending the request to receiving the first byte of the response
Download Time to receive the full response body
Total Sum of all phases
Response Panel

Console

All console.log calls from Pre-request and Post-response scripts appear here, along with any script errors.

Log levels

Method Color
console.log() White, general output
console.info() Blue, informational
console.warn() Amber, warnings
console.error() Red, errors

Script errors (syntax, runtime, uncaught exceptions) are always shown in red with a stack trace.

Core Features

Collections

Collections are folders of requests stored as plain YAML on disk. Every collection maps directly to a directory tree, commit them to Git and collaborate without any Flux-specific tooling.

Collection structure

A collection is one YAML file. Folders live inside that file, not on disk, so moving a request between folders changes one file and shows up as one diff:

~/api-collections/   # a collections folder you opened
  users.yaml        # one collection
  billing.yaml      # another one
  internal/         # a subfolder groups collections in the sidebar
    admin.yaml

Collections folders

Flux can keep several collections folders open at once, so a collection can live inside the repository whose API it tests and be branched, reviewed and cloned with the code:

~/repos/payments-api/api/   # opened as a folder
  payments.yaml
~/repos/billing/api/       # and this one too, at the same time
  billing.yaml

The folder icon in the Collections header adds one; the list above the search box closes one. Closing a folder only removes it from the sidebar and leaves every file where it is. Each collection remembers which folder it came from, so saving always writes back to its own.

When two folders hold a file with the same name, the second collection is shown with its folder as a prefix (billing/api). With a single folder nothing changes.

Organising from the sidebar

Right-click a collection, a folder or a request:

Collection Folder Request
Rename
New request / folder inside
Duplicate
Move to…
Inherited settings
Delete

Renaming happens in place. Move to… asks which collection first and then which folder of it, so a request can be moved to another collection, even one in a different collections folder. Deleting asks to confirm and says what goes with it.

Ctrl + Shift + N creates a collection, and the + button in the Collections header does the same.

Inherited settings

Auth, headers and scripts can be set once on a collection or a folder instead of being repeated on every request. Click the shield next to any collection or folder; it lights up when that level defines something. A folder shows what it would inherit before you change anything.

  • The nearest level wins. Request over folder, closest folder over outer folder, folder over collection.
  • Auth is all or nothing. The nearest definition is used whole, never merged field by field with an outer one, because a half-built credential is worse than none.
  • Headers merge, matched case-insensitively, with the closest level overriding.
  • Scripts concatenate from the outside in rather than overriding, so a collection-level script can fetch a token and a folder-level one can use it.
  • A folder set to None sends no auth even when the collection defines one. Headers and scripts from outer levels still apply.

The same cascade runs when you press Send, in the Collection Runner, on the Tests screen and in the CLI.

Request YAML schema

A collection saves everything the request builder holds, so reopening a request gives back what you built. Only name is required; anything unset is left out of the file.

name: Create User
id: col-1723800000
kind: http
method: POST
path: {{baseUrl}}/api/users
headers:
  Content-Type: application/json
params:
  notify: "true"
bodyType: json
body: '{"name":"Alice","email":"alice@example.com"}'
auth:
  type: bearer
  token: "{{accessToken}}"
scripts:
  preRequest: pm.environment.set("nonce", String(Date.now()));
  postResponse: pm.environment.set("id", pm.response.json().id);
extractors:
  - path: $.data.token
    variable: accessToken
tests:
  - assert: status == 201
  - assert: json.id != null

Fields

Field Meaning
id Stable identifier, written on save. Deleting or reordering requests does not change it.
kind http or grpc. Defaults to http when absent.
path Full URL, or a path appended to the collection's baseUrl
params Query string parameters, as a map
bodyType json, form, multipart, binary, raw or graphql
body The raw body as a string. For form use the form map instead, and for graphql use the graphql block.
graphql query and variables
auth type plus its fields. See Auth.
scripts preRequest and postResponse. Not run by the CLI.
extractors JSONPath rules that write response values into variables. See Extract.
tests One assert per entry. See Tests.
Keep credentials out of the file
Collection files are meant to be committed, so auth values should be {{VAR}} references, never literal tokens. Flux warns when you save a literal one and offers to move it into the environment for you.

Nested folders

Folders hold requests and further folders, at any depth:

folders:
  - name: Admin
    requests:
      - name: List users
        method: GET
        path: /admin/users
    folders:
      - name: Billing
        requests: []

Mixed HTTP and gRPC collections

Collections support both HTTP and gRPC requests in the same folder. gRPC requests include an extra kind: grpc field and a grpc: block. Clicking a gRPC request in the sidebar automatically navigates to the gRPC screen.

Collection Runner

Select a collection in the sidebar and click Run Collection. The runner executes all requests in sequence, shows pass/fail for each test, and produces a summary report. Currently supports HTTP requests, gRPC runner is on the roadmap.

Import

Flux can import collections from Postman v2.1 and OpenAPI 3.0. Go to File → Import or drag a file onto the sidebar.

What comes across

From Postman From OpenAPI
Auth: bearer, basic, API key, OAuth 2.0, AWS SigV4. Collection-level auth is inherited by requests that do not define their own. Auth from securitySchemes: bearer, basic, API key and OAuth 2.0. Credentials come in empty, since a spec does not carry them.
Query params from url.query, skipping disabled ones. Query and header parameters, with their example as the value.
Pre-request and test scripts from the event array. Path parameters become {{variables}}, so an environment can fill them.
Bodies in raw, JSON, urlencoded, form-data and GraphQL, each with its body type set. Bodies for JSON, urlencoded and multipart. When the spec has no example, a sample is built from the schema.
Folders at any depth. Tags become folders; the first servers entry becomes the collection base URL.

Postman tests arrive as post-response scripts and keep working, in the app and in CI.

GitHub Sync
Collections can be automatically pushed and pulled from a GitHub repository. See GitHub Sync for setup.
Core Features

Environments

Environments hold key-value variable sets that are injected into requests at send time. Switch between environments instantly without editing any request.

Variable scopes

Scope Description Precedence
Global Available in all environments and all collections Lowest
Environment Active only when the environment is selected in the top bar Middle
Script (runtime) Set via pm.environment.set() during pre/post scripts, not persisted Above both
Dynamic built-in {{$guid}}, {{$timestamp}}, {{$isoTimestamp}}, {{$randomInt}} Highest — a variable of the same name never shadows one

A global is a default and the environment specialises it: a global BASE_URL pointing at production is overridden the moment a Local environment defines its own. A script writes into the active environment, so a token refreshed by a pre-request script overrides a stale global of the same name.

Substitution is a single pass over the text. A value that itself contains {{VAR}} is not expanded a second time, and a variable that nothing defines is left as written, braces included, so the mistake is visible instead of turning into an empty string.

Creating an environment

1
Open the Environments screen
Click the Environments icon in the NavRail, or press Ctrl + E.
2
Click + New Environment
Give it a name like Production, Staging, or Local.
3
Add variables
Add baseUrl, accessToken, and any other variables specific to that environment.
4
Select it in the top bar
Use the environment dropdown in the TopBar to activate any environment for all requests.

Secret variables

Mark a variable as Secret (lock icon) to mask its value in the UI. Secret variables are stored in the OS keychain and excluded from exports and GitHub sync.

Core Features

History

Flux persists every request you send to a local SQLite database. The History screen lets you browse, search, replay, and export your request history.

Searching history

Use the search bar at the top to filter by URL, method, or status code. The search is instant and works fully offline.

Replaying a request

Click any history entry to load its full request (URL, method, headers, body) back into the Request Builder. Click Replay to send it again immediately.

Exporting history

Click Export to download your full request history as a JSON file. Useful for auditing, sharing, or importing into analytics tools.

Retention

Settings → Data & Privacy → History retention keeps the last 7, 30 or 90 days, or everything. Older entries are deleted when you change the setting and again each time Flux starts, locally and in your synced copy.

Clearing history

Click Clear History in the Settings → Data & Privacy section or from the History screen's overflow menu. This deletes the local database and the copy in your Supabase project, so signing in on another device will not bring it back. The action is irreversible.

History is local only
Request history is stored exclusively in a local SQLite file on your machine. It is never uploaded to any server, even with GitHub Sync enabled.
Core Features

AI Features

Flux integrates Claude (Anthropic) to accelerate testing, debugging, and body authoring. Free to try during the beta, or bring your own key for unlimited use.

Setup

Nothing to configure. During the beta, every signed-in account gets 100 AI actions a month (up to 20 a day) at no cost. On this free tier your prompts are relayed through Flux servers, which is how the quota is applied, and the model is chosen for you.

For unlimited use, go to Settings → AI & Claude, paste your API key (starts with sk-ant-), and select a model. Your key is stored only on your device, and AI calls then go straight from your machine to Anthropic, never through Flux servers. Usage is billed by Anthropic on your own account.

Available models

Model selection applies when you use your own API key. On the free tier the model is chosen for you and may change over time.

Model Best for
claude-sonnet-4-6 Recommended Best balance of speed and quality for all AI features
claude-opus-4-7 Most capable Complex test generation and deeply structured responses
claude-haiku-4-5 Fastest Quick autocomplete and simple debug suggestions

AI features

Test generation

After any successful response, click Generate Tests. Claude analyzes the response schema and generates a complete test suite covering status codes, field types, required keys, and response time. Generated tests appear directly in the Tests tab, ready to run and save.

AI debug assist

When a request fails (4xx/5xx or connection error), the Debug with AI button appears below the status badge. Clicking it sends the request configuration and error to Claude, which returns a plain-English diagnosis and suggested fixes.

Smart autocomplete

With Smart Autocomplete enabled, Flux suggests completions for header names, path segments, and JSON body fields as you type. Suggestions are ranked by frequency and contextual relevance.

Body editing

Right-click inside any Monaco body editor to access Edit with AI. Type a natural language instruction (e.g., "add a nested address object" or "convert this array to paginated format") and Claude rewrites the body in place.

Usage tracking
Settings → AI & Claude shows your cumulative token usage. The meter is informational only, Flux does not enforce a limit.
Core Features

GitHub Sync

Connect a GitHub repository to push and pull collections automatically. Teams use this to share a single source of truth for API requests without any proprietary cloud backend.

Connecting a repository

1
Go to Settings → GitHub
Or navigate directly to the GitHub screen via the NavRail.
2
Authorize GitHub OAuth
Flux opens a browser window for GitHub OAuth. Grant the minimum required permissions (repo read/write).
3
Select a repository and branch
Choose an existing repository or create a new one. Optionally specify a sub-folder where Flux collections live.
4
Pull or Push
Click Pull to download the latest collections from GitHub, or Push to upload local changes.

Auto-sync

Enable Auto-sync on launch to pull the latest version from GitHub every time Flux starts. Changes you make locally are queued and pushed when you click Sync.

Secret variables are not synced
Variables marked as Secret are excluded from GitHub Sync. Never commit credentials to a repository.
Protocols

gRPC

Flux has a dedicated gRPC screen with support for proto files, server reflection, unary invocations, metadata, and a persistent proto library.

Getting started

Click the gRPC icon in the NavRail (grid of squares). The screen is split into a left panel (service browser) and a right panel (invocation and response).

Loading a proto

Import .proto file Server reflection

Import .proto file

Click Import Proto and select a .proto file from disk. Flux compiles it into a FileDescriptorSet using the embedded protoc and lists all services and methods in the left panel.

Server reflection

Enter the server address and click Reflect. If the server exposes the gRPC Reflection API, Flux fetches all service descriptors automatically, no proto file needed.

Proto Library

Click the Bookmark icon next to a loaded proto to save it to the Proto Library. Saved protos persist on disk across sessions in {app_data}/protos/ and appear in the Library section at the bottom of the left panel. Click any saved proto to reload it instantly.

Invoking a method

1
Select a service and method
Click any method in the left panel. The payload editor auto-populates with a scaffold based on the proto message definition.
2
Edit the payload (JSON)
Modify the JSON payload in the Monaco editor. Flux converts it to the protobuf binary format before sending.
3
Add metadata (optional)
Metadata (gRPC equivalent of HTTP headers) can be added in the Metadata tab as key-value pairs.
4
Click Invoke
The response message appears in the right panel, formatted as JSON. Error codes and trailers are displayed separately.

Stream types

Type Status
Unary Available
Server streaming Available
Client streaming Available
Bidirectional streaming Available

The glyph next to each method in the service tree tells you which kind it is. Unary methods show .

Streaming calls

Selecting a streaming method turns Invoke into Start stream. Messages arrive in a log below the request, newest last, each one numbered and timestamped and collapsible.

Control When it appears
Start stream Opens the call. For client-streaming and bidirectional methods the payload is sent as the first message; leave it empty to send none.
Send Client-streaming and bidirectional only. Sends the current payload as another message, so you can edit it between sends.
End Client-streaming and bidirectional only. Signals end-of-stream and waits for the server to finish.
Stop Aborts the call in either direction

The status bar shows whether the stream is open, how many messages have arrived, and how it ended: completed when the server closed it, cancelled when you did.

Streaming does not run in the CLI
The CLI runner is HTTP only, so gRPC requests in a collection are skipped and reported at the start of the run.

Saving to a collection

Click Save to Collection in the top-right of the gRPC screen. The request is saved as a YAML entry with kind: grpc. Clicking it in the Collections sidebar navigates back to the gRPC screen with the request loaded.

Protocols

WebSocket

The WebSocket screen lets you open persistent bidirectional connections and send and receive messages in real time.

Connecting

1
Enter the WebSocket URL
Use a ws:// or wss:// URL. Environment variables are interpolated: wss://{{wsHost}}/events.
2
Add headers (optional)
Connection-phase headers like Authorization are sent during the HTTP upgrade handshake.
3
Click Connect
The status badge turns green and the message log becomes active.

Message log

All sent and received messages appear in a scrollable log. Received messages are shown with a left indicator; sent messages with a right indicator. Each entry shows timestamp, direction, and byte count.

Sending messages

Type a message (plain text or JSON) in the composer at the bottom and press Enter or click Send. Click Disconnect to close the connection.

Connection stays alive while navigating
Switching to another screen does not close the WebSocket connection. Return to the WebSocket screen to see new messages that arrived while you were away.
Protocols

Server-Sent Events

The SSE screen connects to event streams and displays each event in real time, useful for monitoring push notifications, live data feeds, and AI streaming endpoints.

Connecting

Enter an http:// or https:// URL that returns text/event-stream, add any required headers (e.g., Authorization), and click Connect.

Event log

Each SSE event appears as a row in the log showing its event type, id, and data. The data field is auto-formatted if it contains JSON.

Filtering

Use the event type filter to show only specific event types (e.g., only update events, ignoring ping events).

Export

Click Export to download all received events as a newline-delimited JSON file for offline analysis.

Tools

Load Test

Fire a configurable number of concurrent requests against any endpoint and see latency distribution, throughput, and error rates in real time.

Configuration

Parameter Description Default
Total requests Total number of requests to send 100
Concurrency Number of requests in flight simultaneously 10
Timeout Per-request timeout in milliseconds 5000
Method HTTP method to use From active request
URL Target URL (environment variables resolved) From active request

Results

After the run completes, Flux shows:

  • Throughput, requests per second
  • Success rate, percentage of 2xx responses
  • P50 / P95 / P99 latency, percentile breakdown
  • Latency histogram, bucketed bar chart (<50ms, 50–100ms, 100–250ms, 250–500ms, 500ms–1s, >1s)
  • Error count, total failed requests with status codes
Respect rate limits
Always get permission before load testing a production endpoint. Flux does not add any throttling beyond the concurrency setting you configure.
Tools

Mock Server

Run a local HTTP server that returns predefined responses, ideal for frontend development when the real API is unavailable or not yet built.

Creating a mock route

1
Click + New Route
Specify the HTTP method, path (e.g., GET /api/users), and status code.
2
Define the response body
Enter JSON (or any other content type) in the body editor. Supports dynamic values like {{$uuid}} and {{$timestamp}}.
3
Start the server
Click Start. The mock listens on http://localhost:<port> (port configurable, default 3001).

Response configuration

Option Description
Status code Any valid HTTP status (200, 201, 400, 404, 500, …)
Response headers Custom headers returned with the mock response
Delay Artificial latency in ms to simulate slow APIs
Body Static JSON, XML, plain text, or dynamic templates

Request log

Every request the mock server receives appears in the log panel with timestamp, method, path, and matched route. Unmatched requests return 404 and are logged in red.

Tools

Compare

Send the same request against multiple environments simultaneously and compare the responses side by side.

How it works

1
Enter a URL
Type the request URL in the top bar. Use {{baseUrl}} to reference the base URL of each environment.
2
Select environments
Toggle the environment pills below the URL bar. Each selected environment gets its own response column.
3
Click Compare
Flux fires one request per selected environment in parallel. Columns fill with status, latency, and body as each response arrives.

Use cases

  • Regression check: Verify that staging and production return identical responses after a deploy
  • Migration validation: Compare old and new API versions endpoint by endpoint
  • Multi-region testing: Hit us-east, eu-west, and ap-south in one shot
Tools

CLI

The Flux CLI lets you run collections, single requests, and tests from the terminal, ideal for CI/CD pipelines.

Installation

The CLI is bundled with the desktop app. After installing Flux, add it to your PATH from Settings → CLI Tools → Add to PATH.

Running a collection

Point flux run at a YAML file or a directory of them. Only requests that have tests are executed.

# One collection file
flux run ./my-api/users.yaml

# Every collection in a directory
flux run ./my-api

# Supply the variables the collection references
flux run ./my-api --env BASE_URL=https://staging.example.com --env API_TOKEN=$TOKEN

# JSON report for CI
flux run ./my-api --reporter json --output results.json

# Stop at the first failure
flux run ./my-api --bail

Options

Flag Meaning
--env KEY=VALUE Sets one variable, resolving {{KEY}} anywhere in the collection. Repeat it for each variable.
--env-file PATH Reads variables from a .env style file: KEY=VALUE per line, # for comments, optional quotes, a leading export ignored. Repeatable.
--folder NAME Runs only the requests inside that folder, by name or path (Admin/Users)
--reporter console|json|junit Output format. Defaults to console.
--output FILE Writes the report to a file instead of stdout
--bail Stops the run at the first failing request
Secrets come from the environment, not the file
Collections hold {{VAR}} references, so pass the values at run time from your CI secret store: --env API_TOKEN=$API_TOKEN. Nothing sensitive needs to live in the repository.

Chaining requests

What a request captures is available to the ones after it, both through a variable extractor and through pm.environment.set() in a post-response script:

requests:
  - name: Login
    method: POST
    path: /login
    extractors:
      - path: $.data.token
        variable: TOKEN

  - name: Me
    method: GET
    path: /me
    headers:
      Authorization: "Bearer {{TOKEN}}"

Requests carrying assertions always run. One without any still runs when it has extractors or scripts, because that is what the login step of a chain looks like and skipping it would leave the rest of the batch without a token. A request with none of the three is skipped.

The same chain behaves identically when you press Send, in the Collection Runner and on the Tests screen.

Where variables come from

The CLI has no named environments and no global variables — those live in the app, on your machine. In CI every value comes from the command line:

flux run ./my-api --env-file ci.env --env API_TOKEN=$API_TOKEN

Later sources win, so --env on the command line overrides a file, and a second --env-file overrides the first. That ordering is what lets a pipeline keep the shared values in a committed file and override just one of them for a particular job.

A variable that no source defines is left in the request exactly as written, braces and all, rather than becoming an empty string. A request that goes out to {{BASE_URL}}/users fails loudly instead of quietly hitting the wrong host.

Dynamic values

The same built-ins as the app, resolved fresh at each occurrence, so two {{$guid}} in one request are two different ids:

Variable Value
{{$guid}} A v4 UUID. Useful for an idempotency key or a request id.
{{$timestamp}} Milliseconds since the epoch
{{$isoTimestamp}} The current time as ISO‑8601, e.g. 2026-09-09T12:34:56.789Z
{{$randomInt}} An integer from 0 to 999

A built-in wins over a variable of the same name, and substitution runs in a single pass: a value that itself contains {{VAR}} is not expanded again.

Exit codes

Code Meaning
0 Every assertion passed and every request completed
1 An assertion failed, or a request could not be sent

What the CLI supports

A collection saved in the app runs the same way here: auth, query params, form and GraphQL bodies, environment interpolation, folders at any depth, and the same assertion language evaluated by the same engine.

Auth type CLI
Bearer, Basic, API key (header or query) Supported
OAuth 2.0, client credentials Supported. The token is fetched before the request.
OAuth 2.0, authorization code Not possible unattended: the grant needs a browser. Use client credentials in CI.
AWS SigV4 Not supported yet. The request fails with a message rather than going out unsigned.

Scripts

The CLI embeds a JavaScript engine and the same pm shim the app uses, so pre and post-response scripts run in CI exactly as they do on your machine. A pre-request script that fetches a token and sets it with pm.environment.set() works before the request goes out, and headers added with pm.request.headers.upsert() are sent.

Each pm.test() counts as an assertion, so a failing test fails the run and exits 1, and console.log() output appears under its request.

My API   4 requests with tests
  running pre/post scripts on 2 request(s)

  Create user   214ms
      status == 201
      body has an id
      response time is under 200ms
         Expected 214 < 200
    › token set to abc123

What it does not do

The CLI announces these at the start of a run instead of quietly running something different:

  • gRPC requests are skipped. Only HTTP runs here.
My API   4 requests with tests
  skipped 1 gRPC request(s), not supported by the CLI runner
Settings

All Settings

Open Settings from the gear icon in the NavRail (or Ctrl + ,). Settings are organized into sections accessible from the sidebar.

General

Setting Description Default
Default Timeout Time in ms before a request is cancelled 30000
Follow Redirects Automatically follow HTTP 3xx redirects On
SSL Verification Verify SSL certificates (disable only for local dev) On

AI & Claude

Setting Description
Claude API Key Your Anthropic API key, stored locally, never sent to Flux servers
Model claude-sonnet-4-6 (recommended), claude-opus-4-7, claude-haiku-4-5
Auto-generate tests Show "Generate Tests" button after each response
AI debug assist Show "Debug with AI" button on failed requests
Smart autocomplete Autocomplete headers, paths, and body fields using AI

Appearance

Choose between Dark (default), Light, and System themes. The accent color is always Flux Purple (#A855F7).

Keyboard Shortcuts

Action Shortcut
Send request Ctrl + Enter
Command Palette Ctrl + K
New request tab Ctrl + T
Close tab Ctrl + W
Format body Shift + Alt + F
Toggle sidebar Ctrl + B
Go to History Ctrl + H
Go to Environments Ctrl + E
Go to Collections Ctrl + L
Go to Settings Ctrl + ,
Settings

Proxy & Network

Route Flux traffic through an HTTP or SOCKS5 proxy. Useful for corporate environments, VPNs, or traffic inspection tools like Charles or mitmproxy.

Proxy configuration

Field Description
Proxy URL Full proxy URL, e.g. http://proxy.corp.com:8080 or socks5://127.0.0.1:1080
No Proxy Comma-separated list of hostnames to bypass the proxy (e.g. localhost,127.0.0.1)
Proxy Auth Username and password for authenticated proxies
Inspect traffic with mitmproxy
Set the proxy URL to http://127.0.0.1:8080 and disable SSL verification to inspect all Flux requests through mitmproxy running locally.
Settings

Cookie Jar

Flux maintains a persistent cookie jar. Cookies set by responses are automatically sent with subsequent requests to the same domain.

Viewing cookies

Go to Settings → Cookie Jar to see all stored cookies grouped by domain. Each entry shows name, value, path, expiry, Secure, and HttpOnly flags.

Managing cookies

  • Click the delete icon on any row to remove a single cookie.
  • Click Clear All Cookies to wipe the entire jar.
  • Cookies with an expired Expires date are automatically excluded from requests.

Per-request control

To disable cookie sending for a specific request, add the Cookie header manually with an empty value, or use the Pre-request Script to delete specific cookies before sending.

Settings

Data & Privacy

Flux is local first: everything works offline and lives on your machine. Signing in adds optional sync to your own Supabase project. This page explains what is stored, where, and how to delete it.

What Flux stores

Data Location Leaves your machine?
Collections Selected directory on disk (YAML files) Synced to your Supabase project when signed in, and to GitHub if you enable GitHub Sync
History {app_data}/flux.db (SQLite) Method, URL, status, duration and environment are synced when signed in. Request and response bodies are never stored or synced.
Environments Browser local storage Synced when signed in, variable values included. Keep secrets out of committed collections.
Settings Browser local storage (flux-settings) Synced when signed in, except your API key and client TLS certificates
Cookies {app_data}/flux.db (SQLite) Never
Claude API key Browser local storage (flux_claude_key), unencrypted Never synced. Sent only to Anthropic, from your machine.
Client TLS certificates Browser local storage, unencrypted Never
Proto library {app_data}/protos/ Never

Deleting your data

  • Clear history: Settings → Data & Privacy → Clear History
  • Clear cookies: Settings → Cookie Jar → Clear All Cookies
  • Delete all app data: Uninstall Flux and delete the {app_data}/flux directory

Telemetry

Flux is an API client: the URLs, tokens and payloads you work with are the most sensitive things on your screen. None of them ever leave your machine. What follows is the complete list of what Flux can send, and it is deliberately short.

Everything here is controlled from Settings → Data & Privacy:

Toggle Default What it sends
Send usage analytics Off Which sections of the app you open, and that a request was sent — its method, whether the scheme was https, and whether it pointed at localhost.
Send crash reports On The error message, with URLs, file paths, e-mails and credential-shaped strings stripped out before sending.
Share performance metrics Off Response time and status code of a request. No URL.

What is never sent

  • Request URLs — not the full URL, not the path, not even the hostname. An internal host like api.staging.acme.local identifies your employer, so it is dropped too.
  • Headers, request bodies and response bodies.
  • API keys, tokens, cookies or any credential.
  • Collection names, environment names and variable values.
  • Your name, e-mail or the path to your home directory.

How you are counted

When usage analytics is on, Flux sends a random identifier generated on your machine the first time it runs. It identifies a copy of Flux, not a person: it is not derived from your hardware, your account or anything else, and it is not linked to your Flux account even when you are signed in. Clearing the app's local data resets it. Without it there is no way to tell whether a hundred events came from a hundred people or from one, which is the only reason it exists.

Update checks are not covered by these toggles
On start-up Flux asks a server whether a newer version exists, and that request carries your IP address like any HTTP request — it did when the check pointed at GitHub too. The server counts it to estimate how many installs are still active. It stores a salted hash of your IP and user agent, never the address itself; the salt is regenerated daily and discarded after two days, so the hash cannot be reversed or matched across days. Nothing else about you is recorded. To stop the check entirely, block fluxapi.dev and github.com in your firewall — Flux will keep working and simply stop offering updates.

Flux is open source, so none of this has to be taken on trust. The client side is src/lib/analytics.ts — roughly a hundred lines, with the redaction rules covered by tests — and the server side is supabase/functions/.

Your requests go straight to the target API
Flux never proxies, logs or stores the requests you send. Every one goes directly from your machine to the target API. The single exception is the free AI tier: when you have no API key of your own, the AI prompt (which for debug assist includes part of the response you are inspecting) is relayed through a Flux proxy so the quota can be applied. With your own key nothing is relayed. See AI Features.
Settings

Terms of Service

Flux is free and open source under the MIT licence. These terms cover the parts that are not simply the software on your machine: the optional account, cloud sync and the AI free tier.

Last updated: 10 September 2026

The software

Flux is released under the MIT licence. You can use it for anything, including commercially, modify it and redistribute it. That licence governs the software itself, and where it and this page disagree about the software, the licence wins.

As the licence says, Flux is provided as is, without warranty of any kind. You are responsible for the requests you send with it and for having permission to send them.

Accounts

An account is optional: Flux runs without one. If you create one, with an e-mail address or through GitHub, you agree to give accurate details and to keep your credentials to yourself. You are responsible for what happens under your account.

You can delete your account at any time from Settings → Data & Privacy. Deleting it removes what is stored on the server; whatever is already on your machine stays there.

An account may be suspended if it is used to attack the service, to get around the AI limits, or to do something illegal. Where it is reasonable to do so, you will be told why first.

Cloud sync

Sync is opt-in. When it is on, your collections, environments, request history and app settings are stored on the server so that other machines signed into the same account can read them. What is stored, and how to delete it, is set out in Data & Privacy.

Keep your own backups of anything you cannot afford to lose. Collections are plain YAML files on your machine, so a copy or a Git repository is enough. There is no promise that the service will be available at any particular time, and synced data cannot be guaranteed against loss.

Do not put credentials in a collection file. Flux is built so that secrets live in environment variables and collections reference them as {{VAR}}, and it warns you before saving one in plain text.

The AI features

Flux can use Claude, from Anthropic, in two ways:

  • With your own API key. Requests go from your machine straight to Anthropic. The key never leaves your device and never reaches the Flux servers. Your relationship for that use is with Anthropic, under their terms.
  • With the free tier, which needs an account. Prompts are relayed through a Flux proxy, which is what applies the per-account limit, and then on to Anthropic.

The free tier is a beta courtesy with a monthly and a daily limit, both shown in Settings → AI & Claude. Those limits can change, and the free tier can be reduced or withdrawn, without notice. If you depend on the AI features, use your own API key.

Whichever route you use, what you send reaches Anthropic and is subject to their terms and their policies. Do not send anything through the AI features that you are not allowed to share with a third party.

Acceptable use

Do not use Flux or its services to break the law, to attack systems you have no permission to test, or to put someone else's personal data through the AI features without a basis for doing so. Load testing can generate a lot of traffic: only point it at something you are authorised to load test.

Liability

To the extent the law allows, Flux and its author are not liable for loss of data, loss of profit, or any indirect or consequential damage arising from use of the software or the services. Nothing here removes rights that cannot be removed by agreement, including any consumer rights you have where you live.

Changes

These terms can change as Flux changes. Material changes are noted in the changelog, and the date above is updated. Continuing to use the account services after a change means you accept the new terms; if you do not, you can stop using them and keep using Flux locally, or delete your account.

Contact

Questions about these terms, or about an account, go to GitHub issues for anything public, or to the address in Settings → Data & Privacy for anything about your own data.

Flux is free and open source
A star helps other developers find it.
Star on GitHub