A small cross-platform desktop app for storing snippets you paste all the time — credentials, tokens, URLs, boilerplate text — and copying them with a single click.
Data lives entirely on your machine (browser localStorage inside the Tauri webview). Nothing is sent anywhere.
- Tabs → groups → elements — a three-level structure to organize snippets.
- One-click copy — clicking an element writes its value to the system clipboard and shows a toast.
- Element types:
string— copied to clipboardpass— copied to clipboardlink— opened in the default browserdanger-link— opened in the default browser, but only after a confirmation dialog
- Labels — show a friendly name on the button instead of the raw value.
- Context menus — right-click a tab or element to edit or delete it.
- Import / export — save all data to a timestamped JSON file, or load it back.
- Reset — wipe local data.
- Themes — light / dark, persisted.
- i18n — English and Ukrainian, persisted.
- Tauri v1 (Rust) — desktop shell, clipboard, shell-open, filesystem dialogs
- React 18 + TypeScript + Vite 5
- Zustand (
persist+immermiddleware) — state - shadcn/ui + Radix UI + Tailwind CSS — UI
- react-router-dom — routing
- i18next / react-i18next — localization
- sonner — toasts
- Node.js 18+
- Rust toolchain and the Tauri v1 prerequisites for your OS (on Linux:
webkit2gtk,libayatana-appindicator,librsvg, etc.)
npm install
npm run tauri # runs `tauri dev` — starts Vite on :1420 and opens the desktop windowFrontend only, in a browser (Tauri APIs — clipboard, dialogs, shell — will not work):
npm run dev| Script | What it does |
|---|---|
npm run dev |
Vite dev server on port 1420 (strict port) |
npm run build |
tsc type-check, then Vite production build into dist/ |
npm run preview |
Serve the built frontend |
npm run tauri |
tauri dev — full desktop app in development mode |
npm run formatt |
Prettier over the whole repo |
The tauri script is hard-wired to tauri dev, so use the CLI directly for a release bundle:
npx tauri buildArtifacts land in src-tauri/target/release/bundle/ (targets: "all" in tauri.conf.json).
src/
components/ feature components (AddTab, AddGroup, AddElement, CopyElement, …)
ui/ shadcn/ui primitives (button, dialog, select, toast, …)
routes/ Router, MainLayout, Home, Settings
store/ Zustand stores — useDataStore (snippets), useLocalizationStore (lang)
services/ JsonService — import / export / reset
hooks/ useSwitch
types/ data + global types
config/ constants (localStorage key)
i18n.ts inline en/uk translation resources
src-tauri/
src/main.rs Tauri entrypoint + `save_file` command
tauri.conf.json window, bundle and allowlist config
Path aliases: @ → src/, @ui → src/components/ui/ (declared in vite.config.ts and tsconfig.json).
Export produces a JSON array of tabs:
[
{
"title": "Work",
"value": [
{
"type": "group",
"name": "Staging",
"value": [
{ "type": "string", "label": "Admin user", "value": "admin@example.com" },
{ "type": "pass", "label": "Admin password", "value": "hunter2" },
{ "type": "link", "label": "Dashboard", "value": "https://staging.example.com" },
{ "type": "danger-link", "label": "Drop DB", "value": "https://staging.example.com/reset" }
]
}
]
}
]The same shape is kept under the zustand key in localStorage; the selected language lives under localization.
- Values are stored in plain text.
passelements are not encrypted or masked — the type only labels intent. Do not use this for secrets you would not keep in a plain file. - Imported JSON is not validated (
// TODO: validationinsrc/services/json.service.ts) — a malformed file can put the store into a broken state. Export first if in doubt. - The Tauri allowlist is
"all": trueandcspisnull; tighten both before shipping anything public.
Not specified.


