Code Reuse
SkillDev toolsUse when building a UI component, PocketBase hook, page, or app feature and there is proven code to copy from the reference repos. Check here BEFORE writing UI components, PB hooks/routes, form controls, dialogs, auth flows, pagination, or realtime stores from scratch. Catalogs reusable code from pocketbase-sveltekit-starter (sk/src/lib + pb/pb_hooks) and spinspire/recipes. Components are proven but may need adaptation to the current project (runes, oat-css, $app/state).
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Code Reuse skill
What this skill tells your AI
The instructions your AI receives, as published by spinspire/pocketbase-sveltekit-starter in .agents/skills/code-reuse/SKILL.md and read by ahel’s review.
Proven, copy-ready code catalog from reference repos. Reuse before building from scratch.
Sources
| Repo | What to copy | Where it lives |
|---|---|---|
| pocketbase-sveltekit-starter | Frontend lib + components + PB JS hooks | sk/src/lib, pb/pb_hooks |
| spinspire/recipes | Frontend lib + components playground + multi-stack templates | sk/, pb/, py/, rs/ |
⚠️ Adapt, don't paste. These use SCSS + box-icons +
$app/stores+ some legacyexport let. Convert:$app/stores→$app/state, SCSS → oat-css/app.csstokens,export let→ runes ($props/$state/$derived). They are proven patterns, not drop-in code.
1. pocketbase-sveltekit-starter — frontend lib (sk/src/lib)
Core PB client (pocketbase/index.ts)
client— typed PocketBase instance (same-origin by default).authModel— readable store onclient.authStore.onChange; callsinvalidateAll()on auth flips.login(email, password, register?, rest?)— create-if-register thenauthWithPassword.logout()—authStore.clear().save<T>(collection, record, create?)— generic create/update; auto-converts to FormData when a value isFile/FileList(viaobject2formdata). Use for file uploads.watch<T>(idOrName, queryParams?, page?, perPage?, realtime?)→PageStore<T>— realtime paginated list store: subscribes tosubscribe("*"), maintainsresult.items(update=replace, create=append, delete=filter).PageStoreaddssetPage()/next()/prev(); unsubscribe tears down realtime. Good upgrade candidate for our host pool/queue lists.providerLogin(provider, authCollection)— OAuth2 login that backfillsname/avatarfrommeta.webauthnRegister/Login— passkey flow via@simplewebauthn/browser+/api/webauthn/*routes.
pocketbase/ui.ts
alertOnFailure(request)— wraps a PB request; surfaces top-levelmessage+ per-fielddataerrors viaalerts.error().
pocketbase/ components
| Component | Purpose |
|---|---|
FileField.svelte | File-field rows with bindable toBeRemoved toggle-delete; links via client.files.getURL. |
Image.svelte | PB file image with { thumb } param + fallback (internal SVG or via.placeholder.com). |
ImgModal.svelte | Thumb → full-size image lightbox in a Dialog. |
Paginator.svelte | « page X of Y » pager bound to a PageStore. |
components/ — UI building blocks
| Component | Purpose |
|---|---|
Alerts.svelte | Global toasts. Exports alerts object (info/success/warning/error, timeout, html); auto-catches unhandled promise rejections. Place once in layout. |
Dialog.svelte | Native <dialog> modal; trigger snippet gets show; closes on backdrop click. |
Link2Modal.svelte | Internal link → modal via preloadData+pushState+<dialog>; invalidateAll+history.back() on close. |
LoginGuard.svelte | Conditional render on auth (and admin via isSuperuser); otherwise snippet + optional redirect. |
LoginForm.svelte | Sign-in/up tabs, admin checkbox, passkey, OAuth buttons from listAuthMethods(). |
LoginBadge.svelte | Auth pill (avatar+name) → Dialog with passkey register / sign out, or sign-in. |
Nav.svelte | Top nav with active highlighting. |
Delete.svelte | Confirm-and-delete form; navigates after collection.delete(id). |
FileInput.svelte | Styled file input with paste capture + filename list snippet. |
DateShow.svelte | Circular date badge (DOW / mon+day / year). |
LocalStorageStore.svelte | Module ls store mirroring localStorage (JSON-parsed) + debug table. |
RadioText.svelte | Pill radio selector; object or string-array choices; hides inputs, :has() styling. |
Spinner.svelte | CSS spinner; also exports activityStore(f) (store with .run()). |
Stepper.svelte | Step indicator; children snippet gets {data, index, total, step, next, previous}. |
TabGroup/Tab/TabContent.svelte | Tabs via context active store. |
ToggleText.svelte | Pure-CSS two-label toggle. |
metadata.ts
writable({ title, headline, description })global metadata store.
2. pocketbase-sveltekit-starter — PB JS hooks (pb/pb_hooks)
main.pb.js patterns
routerAdd(method, path, handler, $apis.requireAuth())— custom routes./api/hello(auth greeting),/api/sendmail($app.newMailClient()+record.ignoreEmailVisibility(true)),/api/config(public, mergesconfig.jsonviarequire(${__hooks}/util)+ live settings),/api/generate(external HTTP +$filesystem.fileFromURL+RecordUpsertForm).onModelCreate/onModelUpdate(e, "collection")— model hooks scoped to a collection.
util.js helpers (load via require(${__hooks}/util))
parseJSON(bytes)/parseJSONFile(path)— decode PB byte-array JSON from$os.readFile.slugDefault(obj)— setslugtoidwhen empty.doAudit(event, request)— writes anauditlogrecord for collections inAUDITLOGenv var; records collection/record/event/user/admin +dataandoriginal(changed keys only, viarecord.original().publicExport()diff).
auditlog.pb.js
onRecordCreateRequest/UpdateRequest/DeleteRequest→e.next()thendoAudit(...). Pattern: let the operation run first, then audit.
config.json
- Static site config merged into
/api/config.
3. spinspire/recipes — frontend + templates
sk/src/lib
pocketbase/index.ts(151 lines) — trimmed variant of the starter's:client,authModel,save+object2formdata,watch,logout. No webauthn. Uses$app/pathsbase.pocketbase/*.svelte—Paginator,LoginGuard,LoginForm,LoginBadge,ImgModal(simpler variants of the starter's).components/*.svelte—Alerts,DateShow,Dialog,FileInput,Nav,Spinner(subset of the starter's; same patterns).
Component playground (sk/src/routes/components/)
A dev-only route that renders any src/lib/components/*.svelte in isolation with a live exports editor:
+layout.svelte— lists all components viaimport.meta.glob("/src/lib/components/**/*.svelte"), links each to/components/{path}.[...path]/+page.svelte— dynamicallyimport()s the component and renders it insideExportEditor.ExportEditor.svelte— readscomponent.$$.props, renders anInputscontrol per prop, binds values into abindingsobject.Inputs.svelte— input control (text/number/date viaINPUT_TYPESinconfig.ts) withprocessorhooks.config.ts—remotePathwritable (VSCode remote link),HTMLInputTypestype,INPUT_TYPESmap.Remote.svelte— form to configure the "Open in VSCode" path.
Use case: to quickly develop/test a component in isolation with interactive props. Pull the components/ route folder into any SvelteKit project.
pb/ — PocketBase/Go template
main.go— custom PB binary:--publicDirflag, SPA static serving,jsvm.MustRegisterMigrations,migratecmd(JS templates),hooks.Register(app).hooks/hooks.go— Go audit-log + event-driven actions: reads ahookscollection (collection/event/disabled) and executescommand/postactions against the record (JSON piped to stdin). Useful pattern for generic record-triggered automation.entrypoint.sh— build-if-needed (go build, tygo, modd) thenexec "$@".tygo.yaml— Go→TypeScript type generation config.pb_migrations/*.js— JS collection-snapshot migrations.
py/ (FastAPI) & rs/ (Axum)
py/web.py— minimal FastAPI with configurable prefix (FASTAPI_PREFIX, default/apy).rs/— Axum REST with SQLite (db.rs), file upload (upload.rs), experimental live-view (live.rs,livecrud.rs), static SPA serving.- Only borrow these if we add a non-PB backend; otherwise skip.
docker-compose.yml + entrypoint.sh
- Multi-service template (pb, py, rs, sk, mb) — non-root
${UID}:${GID},exposenotports,entrypointinitializes (builds) then runs the container command. Pattern matches our own docker setup.
.opencode/tools/sql.ts
- A bun-based SQL tool for opencode (uses
bun:sqlite/@opencode-ai/plugin); READONLY for safety. Only relevant if we adopt opencode tooling.
When to use which source
- UI components, dialogs, forms, toasts, tabs, pagination, realtime list stores, auth UI → starter's
sk/src/lib(richer; the recipes versions are trimmed copies). - Component playground / dev preview tool → recipes
components/route. - PB custom routes, model hooks, audit logging, config merging → starter's
pb/pb_hooks. - Record-triggered automation (command/post actions), custom PB Go build, FastAPI/Axum backends, multi-service compose → recipes
pb/,py/,rs/,docker-compose.yml. - Generic file upload create/update →
save()/object2formdata(both repos).
Adaptation checklist (apply to every copy)
$app/stores→$app/state(pageobject, not store).- SCSS
<style>→ oat-css classes + tokens insrc/app.css(--brand,--glow,--muted-text; NOT--accent/--mutedwhich oat reserves). - box-icons
<i class="bx bx-*">→ inline SVG or text. - Legacy
export let/$:→ runes ($props,$state,$derived, snippets{@render}). - Rename
$derivedvarstate→live(svelte2tsx crash). client/pbimport path →$lib/pb(our app).- Collection names/fields → ours (
events,entries,users). - Typecheck (
bun run check) + tests (bun test) after adapting.
Signals
- GitHub stars
- 507
- Forks
- 76
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
code-reuse- Source
- github.com/spinspire/pocketbase-sveltekit-starter