Skip to content

areknow/stash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

111 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stash

Save. Sync. Copy in a tap. Stash is a snippet manager for iPhone, iPad, and Mac: capture text, links, code, addresses, and images, keep them in sync with iCloud, and grab them again the moment you need them.

Built with React Built with TypeScript Built with Vite Swift CloudKit App Store Netlify Status

Hero


Table of Contents


Features

Capture and organize

  • Smart tiles — Stash classifies what you save: text, code, link, address, and image, and treats each type appropriately (open in Safari, drop a pin, copy formatted code, and more).
  • Share extension — Save from any app that supports the system share sheet without breaking your flow.
  • Fast copy — Tap a tile to copy with haptics and confirmation; edits are safe with draft handling on Apple platforms.

Everywhere you work

  • iCloud sync — One stash across iPhone, iPad, and Mac; data stays in the user’s iCloud account.
  • Menu bar on Mac — Recent items, paste from clipboard, image import, and screenshot capture without a Dock icon.
  • Marketing site — React + Vite landing and legal pages with build-time pre-rendering: production npm run build emits static HTML for /, /privacy, and /terms (hydrates to the same SPA in the browser).

Developer-facing

  • Native Apple stack — SwiftUI surfaces, shared StashCore library, CloudKit sync with CKSyncEngine.
  • Modern web tooling — React 19, Vite 8, SCSS modules, ESLint + Prettier, Phosphor icons.

Screenshots

Marketing Site

https://stashsnippet.app

Marketing Site

iOS App

macOS App

macOS App


Tech Stack

Architecture overview

flowchart TB
    User[User]
    iOS[Stash iOS / iPadOS]
    MacMB[StashMenuBar macOS]
    ShareExt[StashShareExtension]
    Core[StashCore]
    CK[iCloud / CloudKit]
    Web[Marketing site - Vite React]

    User --> iOS
    User --> MacMB
    User --> ShareExt
    iOS --> Core
    MacMB --> Core
    ShareExt --> Core
    Core -->|CKSyncEngine| CK
    User -->|Reads marketing / legal| Web
Loading

Apple apps (ios/)

  • Swift & SwiftUI — Primary UI for phone, tablet, and menu bar.
  • StashCore — Shared models, content classification, CloudKit sync (StashCloudSync, tile records).
  • CloudKit — Private database sync; custom zone support via sync engine.
  • Share extension — System share sheet target.
  • Push (menu bar) — Used with sync where configured; see CloudKit deployment notes.

Marketing site (web/)

  • Pre-renderingvite build produces a client bundle plus an SSR bundle; scripts/prerender.mjs runs render() from entry-server for each public route and writes fully populated <div id="root">…</div> into static index.html files (SEO-friendly, fast first paint).
  • React 19 — Landing, feature sections, privacy, and terms.
  • Vite 8 — Dev server and production builds.
  • React Router 7 — Client routing; server render path used only at build time for those prerendered pages.
  • SCSS — Global tokens, section styling, component modules.
  • Phosphor Icons — Iconography on the site.

How It Works

  1. User captures content (type, paste, photo, share sheet, clipboard, or screenshot on Mac).
  2. Stash classifies the payload into a tile kind (text, code, URL, address, image).
  3. Local storage + sync persist the tile; CloudKit propagates changes to the user’s other devices.
  4. User recalls the item from the main app or the Mac menu bar—copy, open link, directions, or edit.

Sync-oriented flow

sequenceDiagram
    participant DeviceA as Device A
    participant Core as StashCore
    participant CK as CloudKit
    participant DeviceB as Device B

    DeviceA->>Core: Create / update tile
    Core->>CK: Upload record (CKSyncEngine)
    CK->>DeviceB: Fetch / push notification path
    DeviceB->>Core: Merge remote changes
    Core->>DeviceB: Update UI
Loading

Getting Started

Prerequisites

  • For web/: Node.js 20+ recommended (matches current Vite/React toolchain).
  • For ios/: macOS with Xcode (recent stable), Apple Developer account for signing, iCloud capability, and (for menu bar push) correct entitlements and provisioning as described in the CloudKit doc.

Clone and install (marketing site)

git clone https://github.com/areknow/stash.git
cd stash/web

npm install
npm run dev

Open the URL Vite prints (typically http://localhost:5173) to view the marketing site locally.

Build the static site

cd web
npm run build

Output is under web/dist/ (client assets plus pre-rendered HTML for /, /privacy, /terms). Use npm run preview to smoke-test the production build.

Build and run the Apple apps

  1. Open ios/Stash.xcodeproj in Xcode.
  2. Select the Stash (iOS), StashMenuBar (macOS), or extension scheme as needed.
  3. Choose a simulator or device and run (⌘R).

Brand assets (icons, splash, logos) live in each target’s Assets.xcassets and are maintained per target.


Architecture

Repository layout

stash/
├── web/                    # Marketing site (Vite + React)
│   ├── src/
│   │   ├── pages/          # Marketing, Privacy, Terms
│   │   ├── components/     # Layout + marketing sections
│   │   └── assets/screenshots/
│   ├── scripts/prerender.mjs
│   └── package.json
├── ios/
│   ├── Stash.xcodeproj
│   ├── Stash/              # Main iOS / iPadOS app
│   ├── StashMenuBar/       # macOS menu bar companion
│   ├── StashShareExtension/
│   ├── StashCore/          # Shared logic + CloudKit sync
│   └── CLOUDKIT_DEPLOYMENT.md
└── README.md

Key design decisions

Why CloudKit?

  • First-party sync with no custom backend to operate.
  • Data stays private to the user’s Apple ID.
  • Fits a personal productivity app that already targets Apple platforms.

Why StashCore?

  • One implementation of tile models, classification, and sync for app, menu bar, and extension.
  • Reduces drift between targets when behavior changes.

CloudKit and sync

There is no public HTTP API: the source of truth for user data is CloudKit (private database), coordinated by StashCore.

Before a production release, deploy the CloudKit schema from development to production and verify record types (for example StashTileRecord and fields such as kindRaw, title, textBody, codeBody, imageURLString, imageAsset, timestamps). Full checklist, migration notes, and menu bar push/sync troubleshooting live in ios/CLOUDKIT_DEPLOYMENT.md.


Deployment

App Store

Ship the Stash app (and menu bar product if distributed with it or separately per your App Store setup) through Xcode and App Store Connect. Complete CloudKit schema deployment before the first production release that uses new record definitions.

Marketing site

The site is a static export that already includes pre-rendered HTML for /, /privacy, and /terms from npm run build (not a Node server at runtime). Deploy the contents of web/dist/ to any static host (object storage + CDN, Netlify, Cloudflare Pages, etc.). Configure the host so:

  • /privacy and /terms resolve to their pre-rendered index.html files under those paths (as produced by the build), and
  • client-side routing fallback is consistent with your host’s SPA rules if you add more routes later.

Environment variables

The marketing site does not require secrets for local dev. If you add analytics or API calls later, document keys in a local .env pattern and exclude them from git.


Development

Web

cd web

# Dev server
npm run dev

# Production build + prerender
npm run build

# Typecheck & lint
npm run typecheck
npm run lint

# Format
npm run format
npm run format:check

iOS / macOS

  • Use Xcode schemes and the standard build/test workflow.
  • For sync or push oddities after aggressive debugging, see the defaults reset and entitlement notes in ios/CLOUDKIT_DEPLOYMENT.md.

Project Highlights

Technical challenges addressed

  1. Reliable CloudKit sync — Custom CKSyncEngine-based pipeline with careful lifecycle (single sync controller in menu bar process, schema migration from older containers).
  2. Smart content typing — Heuristics and shared core logic so tiles behave correctly across UI surfaces (badges, actions, copy semantics).
  3. Menu bar + full app — Shared core, different UX constraints (popover, recents, clipboard, screenshots) without duplicating sync.
  4. Marketing performance — Vite builds plus route-level SSR prerender for key URLs.

Contributing

This is primarily a personal / product repository. Ideas and bug reports are welcome via issues; for substantial changes, open a discussion first so direction stays aligned with the App Store app and CloudKit constraints.


License

Private. All rights reserved.

About

Multi-device snippet manager for Apple ecosystem backed by iCloud Private Database.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors