Deixis

Voice input for your product, on your user's own computer where it can be

Somebody has asked you for voice input. A support desk wants agents to talk into the reply box, a field service app wants notes dictated with gloves on, an internal tool wants a bug described rather than typed. Every way of building it has the same problem underneath: the moment you accept audio, you are responsible for it.

Free, with no account and no sign-in.

See it work

The browser's own speech recognition sends the audio to the browser vendor. A speech API makes you a processor of your customers' voice recordings, billed by the minute and defended in every security review. A model inside your own app is a couple of hundred megabytes and an accuracy problem you own forever.

There is a fourth option, and it is the reason this page exists: let the copy of Deixis on the user's machine do it. Your page asks for words; the recognition happens on their processor; the words arrive in your field. While Deixis on the user's computer is running and connected to your site, no audio reaches your servers, ours, or any cloud, because it never leaves the computer it was spoken on. Otherwise (no Deixis, not yet connected to you, or not running), the drop-in mic has a cloud route: the recording goes through Deixis to Cloudflare's speech model and comes back as text. We keep neither the recording nor the words, the audio never touches your servers, and the user is told every time, beside the mic. Try it live on our own page, or read the partner programme for what it costs and what partners earn.

See it work

Three lines: the drop-in mic

<script src="https://deixis-voice.com/sdk.js" data-key="pk_live_…" async></script>
<textarea id="question"></textarea>
<deixis-mic for="question"></deixis-mic>

That is a whole mic button. On every press it decides what to do:

  • In a browser where Deixis has answered before, it records on the user's computer: press to start, press again to stop. While it records, the line beside the mic says "On this computer · Deixis"; afterwards a laptop mark keeps those words as its tooltip.
  • Everyone else, with your key, records in the browser and is transcribed in the cloud. A small red cloud beside the mic marks every such take; press it for a short explanation and the offer of Deixis. If Deixis has answered before but is not running now, that take goes through the cloud and the mark says so.
  • Without a key, or once your cloud minutes are used up, a user without Deixis gets a short offer to get it, with a download link that carries your site, and an "I already have it" for people who installed it some other way.

The words land in the field for names, a textarea, an input or a contenteditable: at the caret, replacing any selection, followed by an input event (at the end of a field the user has not been in). They go in through the field's own value setter, so a React controlled input sees the change. The element changes no word; at most it adds a single space where they meet your text.

What it handles so you do not have to:

  • No request without a reason. Loading the script and rendering the button send nothing. The element reaches 127.0.0.1 only from a press, once Deixis has answered in this browser or the user says they have it, so nobody with nothing installed sees the browser's local-network question.
  • The microphone tick. If the user has not let your site start the microphone, the element names the one tick in Deixis's settings and offers hold-to-talk behind its own button.
  • Everything else that can go wrong: Deixis not running, Deixis still getting its speech model after an install, the browser blocking your site or the microphone, a version of Deixis too old to start the microphone, a take that ran to its limit. Each gets its own short message.
  • Phones, tablets, Linux and ChromeOS. Deixis on a phone does not take dictation for web pages, and there is no Deixis for Linux or ChromeOS. With your key, those get the cloud route; without one, the element renders nothing.

Three events tell your code what happened. All of them bubble out of the element:

document.addEventListener('deixis-transcript', (e) => save(e.detail.text));
// deixis-transcript  { text, route }      route is 'local' or 'cloud'
// deixis-state       { state, route }, on every change
// deixis-error       { reason }: not_granted, not_ready, blocked, not_running, no_credit, busy, …

Call preventDefault() on deixis-transcript to put the words in yourself, for an editor that keeps its own model of the text.

Styling. The button lives in a shadow root, so your stylesheet cannot break it by accident. Five custom properties reach in: --deixis-accent, --deixis-radius, --deixis-font, --deixis-line and --deixis-text. ::part(button) covers the rest, and data-state and data-route on the element let you style one state. Left alone, it wears your page's font and text colour. The cloud line can be restyled through those properties but not hidden: it has no part, and the element overrules the stylesheet tricks that would hide it. Keeping it visible is a condition of the key.

The attributes. On the script tag: data-key, your publishable key, which turns the cloud route on; data-terms, up to 36 comma-separated words the cloud should expect (product names, people, jargon); data-partner, your slug, which download links carry (with a key it is optional: they carry your site, one of your key's); data-name, the name the element's sentences use for your site (your page title by default); and data-simulate. On the element: for; label for the button's accessible name, "Dictate" by default; disabled, which stops a press from starting a take (while your assistant is still replying, say) but never stops a take already running from being stopped; and line. The line beside the mic goes on the side that keeps the button still, measured from your layout: before it at the end of a row (after a one-line field, say), after it elsewhere. line="start" or line="end" decides it instead, and right-to-left pages are mirrored.

Loading it. In the head, or when the component with the mic first mounts, so a page whose visitors never dictate loads nothing at all. It upgrades any <deixis-mic> already in the page; until then the element draws nothing.

Testing without Deixis. data-simulate plays one scenario with canned words, with no Deixis, no microphone and no request. Leave the value empty for the ordinary path, or name one: offer, mac, not_granted, blocked, asking, outdated, not_running, not_ready, no_model, busy, expired, failed and phone, or the cloud route's cloud, cloud_miss, cloud_failed, no_credit, cap_reached and phone_cloud. The simulated words are always "This is Deixis in simulate mode. No microphone was used.", and a simulated mic renders on a Linux test machine too, in a browser or in jsdom.

A Content Security Policy needs script-src https://deixis-voice.com https://challenges.cloudflare.com, frame-src https://challenges.cloudflare.com (the cloud route's Turnstile check, which runs unseen unless Cloudflare wants a click), and connect-src http://127.0.0.1:47831 http://127.0.0.1:47832 http://127.0.0.1:47833 https://api.deixis-voice.com. In current browsers the element's styles come from a stylesheet built by the script, so style-src needs nothing added. Safari before 16.4 cannot build one and falls back to a <style> element, which a style-src without 'unsafe-inline' blocks: there the button works but is unstyled.

The file is served minified. Every rule in it has its reason written beside it in the commented source, which is the same code.

About ten lines

If you want your own button rather than ours, the element is built on a handful of calls you can use directly. They talk only to Deixis on the user's computer.

Load the SDK and ask. available() tells you whether there is a Deixis on this machine willing to talk to your origin, and dictate() asks the user for one dictation.

<script src="https://deixis-voice.com/sdk.js"></script>
button.addEventListener('click', async () => {
  const { installed, download } = await deixis.available();
  if (!installed) return showDownloadLink(download);  // a download that knows your site

  // The user holds their Deixis key and speaks; the words come back cleaned.
  input.value = await deixis.dictate();
});

That is the whole integration for the common case. For these calls there is no API key, no account, no npm dependency, no build step and no server component on your side.

A web page's microphone button, the loopback door on the same machine, the Deixis overlay, and the text arriving back in the page's field
Your page asks the copy of Deixis on that machine for words. The audio and the recognition never leave the user's computer, and nothing goes through us.

If you want the microphone button most apps actually want — press to talk, release to stop, with no keyboard chord for the user to learn — there is a second pair of calls, and the user grants that separately:

await deixis.start({ onPartial: (text) => (preview.textContent = text) });
// …the user speaks, your button says Stop…
input.value = await deixis.stop();   // the finished, cleaned transcript

While that runs, Deixis shows its own overlay naming your site, with its own Stop, and ends the recording if your page goes away or after ten minutes. That is deliberate: a microphone opened by a web page should always be visibly one, and closable by the person it is pointed at.

Three rules the design puts on you

Each exists because the alternative would be a way to abuse somebody's microphone. The drop-in mic keeps all three for you; build your own button and they are yours to keep.

1. Call it from a real user action, never on page load. Chrome gates a page's first request to a loopback address behind a Local Network Access prompt, and while it is unanswered the request neither succeeds nor fails: at load time, a hung page with nothing in the console. From a click it is a one-time question, and after the user allows it a probe costs about two milliseconds.

2. installed: false means "could not reach it", not "not installed". Deixis may be running with the door off, your origin may not be on the user's list, or they may not have answered the browser yet, and a page that is not allowed to talk to Deixis is told nothing about whether it is there. Treat it as "no voice right now". The one thing you can tell apart is the browser's own refusal, permission: 'denied', which no retrying fixes until the user unblocks your site.

3. You are never given the microphone, only the words. dictate() does not open anything: it asks Deixis to route the user's next hold-to-talk to you, and if they never speak, your promise rejects on its deadline. Your page sees neither the audio nor anything else the user keeps in Deixis.

Design for the missing grant, too. "Start and stop the microphone" is off for every site until the user ticks it, or leaves it ticked on the first-run card of a site on Deixis's own list of partners, so a start() without it rejects with not_granted — offer the button, and fall back to dictate() with a line telling the user to hold their key. A fresh install's start() can also reject with not_ready while Deixis downloads its speech model: the error's model is downloading while that runs, and missing when the user has to open Deixis to start it.

When Deixis is not on the machine

This is where most local-companion integrations quietly fail: the user installs it, presses your button, and nothing happens, because the app has no idea your site exists.

So do not write the download link yourself. available() hands you one:

const { installed, download } = await deixis.available();
if (!installed) link.href = download;   // carries your site's name

An installer fetched through that link arrives knowing where it came from. On its first run Deixis puts one card on screen with your site's name on it — Allow or Not now — and Allow does the four settings steps at once: the door on, your origin listed, the permissions decided under your name. If the speech model is not on the computer yet, the card says so, with its size, and Allow downloads it too.

The card Deixis shows on first run: the site's name, Allow and Not now, and a separate unticked microphone permission
An installer downloaded from your site arrives knowing where it came from, so the user answers one card instead of finding a settings panel.

Note what the card is: a request, answered by the person. A filename is chosen by whoever serves the file, so an installer that granted on the strength of one would let any page allowlist itself, and open a microphone. So the microphone tick starts unticked for an ordinary site, and "Not now" is nothing at all. On the card of a site on Deixis's own list of partners it starts ticked, and the user can untick it.

A page on plain http, on localhost or on a non-standard port gets the plain download link, because the installer only carries a site it could safely offer. The web door arrived with Deixis 1.1.12; on an earlier version available() reports that nothing answered.

If your product is not a web app

A desktop program connects to the same engine through a named pipe on Windows or a unix socket on macOS, never a TCP port, using an address and a key Deixis writes beside the user's settings while the door is open. Five requests are all it may send, each a tick the user controls: a short question on the HUD, a letter on the mode palette, a dictation the user routes to it, a click the user makes on screen, and a line typed into a field. The last two are off for every program until the user switches them on. core/examples/client.rs drives all five, and the local connections docs have the whole model.

A server does not connect to Deixis at all: Deixis pushes to it. Point a webhook at your URL and every finished note, grab or translation arrives as one HMAC-signed JSON POST; the webhook docs verify one in Node.

Just dictating into your own tools? Deixis already types into Claude Code, Cursor, VS Code and Windows Terminal.

What it costs, for you and for them

On the user's computer, nothing, on both sides. The SDK is a static file, and dictation in Deixis is free forever with no account, so "install Deixis" is not a purchase you ask your users to make. What people pay us for is the optional cloud tier (cleanup, translation, meeting notes) at $49 a year, and nothing on this page needs it.

The cloud route is the part that costs, and you pay for it, not your users: minutes prepaid against your key, starting with 10,000 free ones, good for a year. When they run out the cloud route pauses, and the mic offers Deixis on a computer and stands down where Deixis cannot run, for up to an hour after you top up. Your users never see a balance, and every user who moves to Deixis stops costing you cloud minutes, whether or not they ever pay us. The partner programme has the prices in one place. Partners are set up by us, keys included, on these terms: write to support@deixis-voice.com with your site's address.

What it will not do

  • It is not a speech API. There is no endpoint you can call from your backend, and no way to transcribe a file your server holds. The cloud route answers only the element, on your own site's pages, behind your key and a Turnstile check, with the user present and told.
  • Seven languages. Deixis dictates in the one its user set (which).
  • Windows needs AVX2 (2013 or later); macOS needs 13 or later on Apple silicon. There is no Linux build; on Linux the drop-in mic uses the cloud route or draws nothing.
  • You cannot pre-allow yourself, silently enable the door, or read anything the user has not handed you in the moment. Every one of those is refused rather than rate-limited.

Before you ask

Questions people search for

Does any audio reach my servers or yours?

Your servers, never. Ours, only on the cloud route, for a user whose Deixis has not connected to your site, is not running, or who has none: their recording passes through our server to Cloudflare's speech model and the text comes back. We keep neither the recording nor the words, Cloudflare does not train on them, and the user is told on every take. With Deixis running and connected to your site, recognition happens on the computer and nobody receives the recording.

Do I need an API key or an account?

For the cloud route, a publishable key, which we issue; it sits in your page and names your sites. For the local route and the low-level calls, no: the door is on the user's machine, and there is no registration step for you or for them.

What happens if the user does not have Deixis?

With a key, the drop-in mic transcribes in the cloud and says so, with the offer of Deixis behind the line. Without one, it offers Deixis. available() returns installed: false along with a download link that carries your site's name, so the copy they install can offer them your site on first run with a single Allow.

Can my page turn on the user's microphone?

On the user's computer, only if they have ticked "Start and stop the microphone" for your origin, which is off by default except on a partner's first-run card. Without it, start() is refused and you fall back to dictate(), which needs the user to hold their own key and speak. On the cloud route the browser asks the user itself, as for any site.

Can I use this in a desktop app rather than a web page?

Yes — a local pipe on Windows or a unix socket on macOS, with five requests the user grants individually, and a worked example in the repository. See local connections.

Do partners earn commission?

Yes: 20%, for life, of every Pro or Team payment after tax and payment-processing fees, from users who first pay within three months of arriving through you. Cloud credit or cash, monthly from $50: see the partner terms.

Keep reading

Best dictation software for Windows

Fifteen Windows dictation tools compared, every fact dated from the maker's own pages — including what our own tool cannot do. Read the disclosure.

Offline dictation on Windows

Dictation that works with no internet: speech recognition on your own device, free, no account. Which Windows speech-to-text tools genuinely run offline.

Free voice to text on Windows that types where you are

Free dictation for Windows that types into any app: hold a key, speak, and punctuated text lands at your cursor. Recognition runs on your own processor.

The first five minutes, from the installer to your first words

From the Deixis installer to your first dictated sentence in another app, then one more thing worth trying. Windows and Mac, with no account.

Voice typing for your whole team, on one invoice

What a Deixis seat buys a software team, what stays free without one, the price, and how to bring a whole team on in an afternoon.

What you are downloading

This is Deixis, a desktop app for Windows.

The Download button hands you a signed Windows installer, Deixis_<version>_x64-setup.exe, published by Dappit — Windows names the publisher before it runs. There is no bundled extra software and no toolbar. Deixis needs no account to install, and none of what it does on your own PC is behind a sign-up. What it runs on.

It installs for your account alone, with no administrator prompt, and starts with Windows until you switch that off in Settings → Startup. On a PC without Microsoft’s WebView2 runtime, which Windows 11 already has, the installer fetches it from Microsoft. How to uninstall it · The licence · Privacy policy · Terms of service · support@deixis-voice.com

Before you go

Deixis is free on Windows.

  • Hold Ctrl+Win, speak, let go: the words are typed wherever your cursor is.
  • No account and no sign-in. Your speech is recognised on your own PC.
  • A signed installer from Dappit, with nothing else bundled.

Dictation

Hold a key, speak, let go

Your words are typed wherever your cursor is: a terminal, a ticket, an email or a chat. Recognised on your own PC.

Point

Talk, and point at what you mean

Click the field or the button you are talking about while you speak. It all lands as one brief: a plain Markdown file on your disk, with every grab saved beside it.

Screenshot

Screenshots you can mark up

Freeze the screen, drag out the part you want and draw on it, then copy it or save it. With a Deixis account you can also share it as a link.

Recording

Screen recordings, kept in Videos

Record your screen and play it back from Videos. With a Deixis account you can send it as a link instead of a file.

Meetings

Meetings, transcribed on this machine

Record a call or a room. Nothing joins the call, and the transcript is made on your own PC.

Two keycaps, Ctrl and Win, held down and lit teal from underneath.

Hold a key. Speak. Keep working.

Deixis is free, needs no account, and runs on your own device. Everything on this page is in the current release.

v1.3.2 · 64‑bit Windows 10/11 on Intel or AMD · macOS 13 on Apple silicon · 51 MB · nothing else to install · Android on Google Play

Everything on this page about Deixis is from its documentation for the current release. Something out of date? Tell us.