Skip to content

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Askie AI

🐾 Askie AI

A friendly, privacy-first AI chat assistant, hand-drawn sketchbook style, that runs entirely in your browser.

No server Β· No account Β· No tracking Β· Bring your own OpenRouter API key Β· installable as an app Β· no build step, no framework.

▢️ Try it Β· πŸ› Report a bug


πŸ“‘ Contents


✨ Features

πŸ’¬ Streaming chat. Full Markdown rendering β€” headings, code blocks, lists, links β€” all sanitized before it ever touches the page.

πŸ”‘ Bring your own key. Paste an OpenRouter API key in Settings and you're chatting; the key never leaves your browser except to call OpenRouter directly.

πŸ’Ύ Local persistence. Chat history and settings are saved in localStorage, so your conversation survives a refresh.

πŸŽ™οΈ Voice input. Dictate messages via the Web Speech API on Chromium-based browsers.

πŸ“‹ Copy & retry. One-click actions on any message, plus swipe-to-copy on touch devices.

πŸ“΄ Installable PWA. Add it to your home screen and the app shell keeps working offline.

β™Ώ Accessible. Every interactive element is a real, focusable, labeled control β€” built for keyboard and screen-reader use from the start.

🌍 Model-agnostic. Talk to GPT-4o, Claude, Gemini, Llama, DeepSeek, Qwen, or anything else available on OpenRouter, without running a backend of your own.


πŸ”’ Why it's safe to paste in an API key

This is a fair question for any "bring your own key" tool, so here's the actual threat model:

  • πŸ–₯️ 100% static. There is no backend that could see, log, or leak your key.
  • πŸ“ One destination. Your key lives only in this browser's localStorage and is sent, with every request, straight to https://openrouter.ai β€” nowhere else.
  • 🧱 Locked-down CSP. A strict Content-Security-Policy restricts connect-src to 'self' and openrouter.ai only, so even a hypothetical script-injection bug couldn't exfiltrate your key to a third-party server.
  • πŸ”— Pinned dependencies. Every third-party script is pinned to an exact version with a Subresource Integrity hash, so a compromised CDN can't silently swap the code that runs.
  • 🧼 Sanitized output. All model output is parsed as Markdown and sanitized with DOMPurify before render β€” the model can't inject scripts, images, or styling into the UI.

That said: localStorage is readable by anyone with access to this browser profile. Don't use this on a shared or public computer, and use an OpenRouter key with a spend cap you're comfortable with.


πŸš€ Installation and usage

There's no build step β€” it's plain HTML/CSS/JS. To run it locally, serve the folder over HTTP (opening index.html directly as a file:// URL breaks the Content-Security-Policy and service worker):

# from the project folder, pick whichever you have installed
python -m http.server 8000
# or
npx serve .

Then open http://localhost:8000, click Settings, and paste in an OpenRouter API key.

πŸ“² Installing as a PWA

Platform Steps
Desktop (Chrome/Edge) Click the install icon (βŠ•) in the address bar
Mobile (Safari/iOS) Tap Share, scroll down, tap Add to Home Screen
Mobile (Chrome/Android) Tap the three-dot menu, select Add to Home screen

Once installed, the app shell works offline, and your chats and settings stay saved locally on your device.


πŸ“‚ Code structure

AskieAI-public/
β”œβ”€β”€ index.html                 Markup, inline styles, CSP, manifest/meta links
β”œβ”€β”€ app.js                     All client-side logic: chat, storage, settings, voice, PWA install
β”œβ”€β”€ sw.js                      Service worker β€” caches the app shell for offline use
β”œβ”€β”€ .nojekyll                  Tells GitHub Pages to skip the Jekyll build step
β”œβ”€β”€ robots.txt
β”œβ”€β”€ sitemap.xml
β”œβ”€β”€ README.md
β”œβ”€β”€ PatrickHand-Regular.woff2  Self-hosted webfont (Patrick Hand), used everywhere
β”œβ”€β”€ askieogimage.png           Open Graph / Twitter share image (1200Γ—630)
└── favicon/
    β”œβ”€β”€ site.webmanifest       PWA manifest (name, icons, start_url, theme colors)
    β”œβ”€β”€ favicon.ico / favicon.svg / favicon-96x96.png
    β”œβ”€β”€ apple-touch-icon.png
    └── web-app-manifest-{192,512}x512.png

πŸ› οΈ Tech stack

No framework, no bundler, no node_modules β€” just three pinned dependencies loaded from jsDelivr with Subresource Integrity:

Library Purpose
marked Parses assistant responses as Markdown
DOMPurify Sanitizes the resulting HTML before render
OpenRouter The actual LLM API β€” not a dependency in the code, but the whole point

⚠️ Known limitations

  • πŸŽ™οΈ Voice input is Chromium-only. It relies on the Web Speech API, which is only implemented in Chromium-based browsers (Chrome, Edge) β€” Firefox and Safari users won't see it work.
  • πŸ“΄ No sync. Chat history is per-browser, per-device β€” there's no sync, since there's no account or server to sync through.
  • 🌐 Offline chat still needs a connection. The service worker caches this app's own files for offline use; it deliberately does not cache OpenRouter responses, so you still need a connection to actually chat.

About

A free, privacy-first AI chatbot you run with your own OpenRouter key. No account, no server, no tracking β€” just chat. 🐾

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages