Pins: il mio bookmark manager serverless & AI‑powered 📌🤖

Pins: il mio bookmark manager serverless & AI‑powered 📌🤖

7 dicembre 2025·Sandro Lain
Sandro Lain
lettura in ~9 minuti (1668 parole, 1 immagini)

Lista di segnalibri in stile Vaporwave

Se c’è una costante nella vita di chi sviluppa, è questa: creiamo più link interessanti di quanti neuroni siamo disposti a dedicare a ricordarli. Ogni tanto proviamo a essere disciplinati con i segnalibri del browser, poi arrivano tre nuovi device, due profili, un browser alternativo “che devi assolutamente provare” e il castello crolla. 🙃

Da qui nasce Pins (https://pins.fullstackdeveloper.it): un bookmark manager minimalista, serverless e con un cervello AI di supporto, costruito con un’unica pretesa: i miei link, le mie regole, i miei dati. Non è solo un archivio privato: è anche un bookmark manager pubblico, pensato per condividere in modo ordinato le risorse che considero davvero utili, senza algoritmi che decidono al posto mio cosa “merita” di essere visto.

Perché costruire un bookmark manager nel 2025? 🤔

Onestamente? Perché i servizi esistenti sono ottimi… finché non cominciano a darti fastidio.

Pocket, Instapaper, i segnalibri del browser: fanno il loro mestiere, ma spesso significano dati bloccati in silo, feature che non userai mai, notifiche che non hai chiesto e una quantità di bloat che cresce alla stessa velocità della tua lista “da leggere”.

Io invece volevo tre cose molto semplici:

  • Controllo totale dei dati: niente lock‑in, niente “esporta in CSV quando ti ricordi”, niente dipendenza dall’umore di qualche roadmap aziendale.
  • Flessibilità architetturale: sperimentare con un flusso moderno (statico + serverless + AI) senza montare l’ennesimo backend monolitico che nessuno manterrà.
  • Esperienza rapida quanto un’app nativa: tocco, condividi, confermi e il link è salvato. Se devo pensare, ho già perso.

Sì, è un sistema leggermente over‑engineered per salvare URL. Ma è anche un laboratorio perfetto per mettere insieme Go, funzioni serverless e AI in qualcosa che uso ogni giorno.

Filosofia: own your data, sul serio 🔐

La frase “own your data” è ovunque, ma spesso è più uno slogan marketing che una proprietà concreta. Con Pins ho cercato di renderla meccanicamente vera:

  • i segnalibri vivono in un semplice file YAML dentro un repository Git;
  • ogni modifica è un commit, con storico completo e reversibile;
  • se domani mi stanco di Pins, clono il repo e faccio altro con gli stessi dati.

Nessun database esoterico, nessun formato proprietario da decodificare fra cinque anni, nessun abbonamento a sorpresa. Se sai usare git clone, sei già a metà dell’opera.

Lo stack: statico fuori, vivo dentro 🧱

Architetturalmente Pins è una piccola dimostrazione di come si possano combinare strumenti sobri in modo piuttosto elegante.

Frontend: Hugo
Ho scelto Hugo come generatore statico per un motivo banale: è veloce, prevedibile, testabile. Sputa fuori HTML e CSS puliti, senza sorprese, e mi permette di modellare la UI come una semplice lista di segnalibri filtrabile e ricercabile. In più è estremamente rapido a generare contenuto statico rispetto a molte soluzioni basate su runtime Node.js: quando ogni nuovo bookmark scatena una build, avere tempi di generazione bassi fa la differenza tra un flusso piacevole e uno che ti fa pentire di aver aggiunto l’ennesimo link.

Su questo ho costruito un tema personalizzato, ispirato vagamente all’estetica Vaporwave: colori al neon, contrasti decisi, dark mode predefinita. Perché sì, anche un elenco di link merita un minimo di dignità visiva. 😄

Hosting: Netlify
Il sito statico vive su Netlify, che gestisce:

  • la serving dell’HTML generato da Hugo;
  • la CI/CD basata sui commit Git (ogni nuovo segnalibro = nuovo deploy);
  • le funzioni serverless che costituiscono il piccolo backend di Pins.

Il risultato è un sistema dove il frontend è statico, ma il flusso di scrittura è dinamico e reattivo.

Database: Git & YAML
Qui arriva la parte che di solito o fa brillare gli occhi, o fa storcere il naso: Git come database.

Tutti i bookmark sono memorizzati in un file bookmarks.yaml. Ogni nuova voce viene aggiunta in testa alla lista e salvata con un commit dedicato. Questo significa:

  • storico completo “gratis”;
  • possibilità di navigare nel tempo;
  • rollback istantaneo se qualcosa va storto.

Non è una soluzione universale, ma per un archivio personale di link ha una proprietà molto interessante: la semplicità batte la sofisticazione quasi ogni volta.

Backend: funzioni serverless in Go
La logica di scrittura è implementata come Netlify Functions scritte in Go: servizio stateless, esecuzione rapida, tipizzazione forte. Ogni funzione fa poco, lo fa chiaramente e termina. Nessun server da manutenere, nessun processo da patchare di notte.

Il flusso di aggiunta: dalla condivisione al deploy ✨

Un bookmark manager non vive di architettura elegante, vive di attrito minimo. Se salvare un link richiede tre passaggi mentali, hai già perso metà dei contenuti.

Pins ruota attorno a un gesto semplice: condividi da mobile → conferma → fatto.

Il trigger: lo Shortcut su iOS 📲

Su iPhone ho creato un Comando Rapido agganciato al menu di condivisione di iOS. Quando trovo un articolo interessante, faccio:

Condividi → “Salva su Pins”.

Lo Shortcut prende l’URL della pagina corrente e lo invia alla prima funzione serverless. Nessuna app da aprire, nessun campo da compilare a mano.

Step 1: estrazione e AI che fa il lavoro sporco 🧠

La prima funzione (extract-metadata) riceve l’URL e inizia il suo lavoro dietro le quinte:

  1. scarica l’HTML della pagina;
  2. estrae i metadati classici (titolo, description, Open Graph);
  3. isola il contenuto principale e lo traduce in qualcosa di più digeribile per un modello linguistico, tipicamente Markdown;
  4. invia il contenuto a un modello come Google Gemini con un prompt molto specifico: “Descrivi questo sito in modo conciso per un bookmark (max 2‑3 frasi, in italiano)”.

Il risultato è un JSON essenziale: titolo e descrizione generata dall’AI, pronti per essere mostrati allo Shortcut.

Dal punto di vista concettuale, l’AI qui non è “magia”: è un editor stacanovista che legge gli articoli al posto mio e mi propone un riassunto decente da rivedere.

Step 2: human in the loop (sempre) 👀

Quando lo Shortcut riceve i dati, apre un piccolo popup: vedo il titolo suggerito e la descrizione generata.

Posso:

  • confermare al volo;
  • accorciare quando il modello si fa prendere dall’entusiasmo narrativo;
  • correggere quando la descrizione ha quell’aria di “non ho letto davvero l’articolo, ma grazie per averci creduto”.

Questo step è fondamentale. L’AI è un’ottima assistente, ma non ha gusto personale, memoria emotiva, né idea di quali link rappresentino davvero me. La curatela umana è il vero valore del sistema: senza di quella avrei solo un altro feed generato automaticamente.

Step 3: persistenza su Git (Function 2) 🗂️

Una volta che approvo il risultato, lo Shortcut invia i dati finali a una seconda funzione (add-bookmark). Qui succede la parte più “artigianale” del flusso:

  1. la funzione usa le API di GitHub per scaricare l’ultima versione di bookmarks.yaml;
  2. aggiunge il nuovo bookmark in cima alla lista, con URL, titolo, descrizione e timestamp;
  3. crea un commit con un messaggio del tipo Add bookmark: [URL] e lo “pusha” sul repository.

Niente code path esoterici, niente transazioni distribuite. Ogni link è una piccola storia che lascia una traccia chiara nello storico Git.

Step 4: deploy automatico, senza pensarci troppo 🚀

Appena GitHub riceve il commit, Netlify innesca il pipeline di build: Hugo rigenera il sito statico, Netlify lo pubblica e in meno di un minuto il nuovo bookmark è online.

Dal mio punto di vista, l’esperienza è questa: condivido un link sull’iPhone, controllo due frasi, chiudo. Quando apro pins.fullstackdeveloper.it, il segnalibro è già lì, inserito nel flusso come se fosse sempre esistito.

Alcuni dettagli che fanno la differenza 🧩

Dietro un flusso così lineare ci sono un paio di scelte progettuali che tengono insieme l’esperienza.

Go per le funzioni serverless
Usare Go per le Netlify Functions tiene basso il tempo di cold start e alza il livello di disciplina tipizzata. Strutture chiare, errori espliciti, nessuna “magia” nascosta dietro runtime troppo generosi.

Fallback intelligenti
Quando l’AI non risponde, va in timeout o semplicemente produce qualcosa di poco utilizzabile, la funzione non si offende: fa fallback sulla meta description classica della pagina. Peggio di così? Ci sono sempre le mie dita sulla tastiera dello Shortcut.

Sicurezza minimale ma concreta
Le API che muovono Pins non sono pubbliche in senso tradizionale. Le richieste sono firmate da una chiave condivisa (X-API-Key) tra Netlify e il mio iPhone. Non è crittografia quantistica, ma evita che chiunque con un curl annoiato possa iniziare a spammarmi il database dei segnalibri.

Etica dell’over‑engineering (quando ha senso) 🛠️

Costruire un sistema del genere “solo” per salvare link potrebbe sembrare un esercizio di stile. E in parte lo è. Ma è un esercizio con un obiettivo molto concreto: allenare la capacità di progettare sistemi moderni che restano semplici da spiegare.

Ogni pezzo dell’architettura ha una ragione:

  • il sito statico per la robustezza e la facilità di caching;
  • le funzioni serverless per avere logica dinamica solo dove serve;
  • Git come fonte di verità per unire storico, versioning e portabilità;
  • l’AI come strumento di supporto, non come oracolo infallibile.

La parte interessante non è tanto il fatto di aver usato un modello linguistico, quanto il modo in cui rimane sotto il controllo umano. Nessun link viene salvato senza che io abbia almeno dato uno sguardo al testo. Nessuna descrizione entra nel mio archivio senza passare per il filtro della mia attenzione.

In un’epoca in cui rischiamo di delegare all’AI anche le opinioni, progettare strumenti dove la macchina assiste e l’umano decide è un piccolo atto di igiene mentale.

Cosa mi porto a casa da Pins 🌱

Pins, alla fine, è un promemoria pratico di alcune idee semplici:

  • i tuoi dati valgono più di quanto pensi: trattali come patrimonio, non come scarto digitale;
  • la semplicità architetturale vince spesso sulla complessità “da curriculum”;
  • l’AI brilla quando la usi come redattore stanco ma instancabile, non come sostituto del giudizio umano;
  • i side project migliori sono quelli che usi davvero, non quelli che invecchiano in una cartella experiments/.

È un sistema forse esagerato per trecento link? Probabile.
Ma è mio, è economico (dentro i limiti dei free tier) e soprattutto è un terreno di gioco dove architettura moderna, etica dei dati e piccole abitudini quotidiane si incontrano.

E se domani volessi smettere di chiamarlo “Pins”? Nessun problema: basterebbe rinominare il repo. I segnalibri resterebbero lì, pazienti, in attesa del prossimo over‑engineering.

Ultimo aggiornamento il