Reclaiming the File System: Inside GAGGZ1/Travel-Story

Why a digital travel journal chose local disk storage over cloud buckets, and the anatomy of a self-contained MERN architecture.

6 min read • View on GitHub • More from GAGGZ1

A classic leather-bound travel journal being assembled by mechanical arms, with miniature wooden filing cabinets instead of pages, into which polaroids are being slotted. This represents the self-contained, local-first memory architecture of the application.
Travel-Story bypasses the cloud, opting to store user memories directly on the server's local disk.
Key Takeaways

Escaping the S3 Bucket

In an era where every coding tutorial immediately reaches for an AWS S3 bucket or Cloudinary account, Travel-Story makes a deliberate and refreshing choice. It relies entirely on local disk storage. The most interesting aspect of this project is that it functions as a completely self-contained, independent unit.

The application uses Express and multer.diskStorage to handle file uploads. This requires a precise two-step process. First, the client uploads an image to an endpoint that saves the physical file and returns a local URL. Second, that URL is attached to the story payload and saved to MongoDB. To prevent the server from filling up with orphaned files, the deletion endpoint executes fs.unlinkSync. This native file system command ensures that when a database record vanishes, the physical image vanishes with it.

The lifecycle of a local file upload and deletion in the Travel-Story architecture, highlighting the critical cleanup phase.

Chronology Over Algorithms

The data model fundamentally shapes the user experience. By examining the travelStory.model.js schema, the application's priorities become clear. It uses a visitedDate field and an array of visitedLocation strings to anchor every memory in time and space.

There are no generic engagement metrics. No tracking of likes or algorithmic sorting. Instead, the frontend utilizes React Day Picker to drive database queries directly. The user navigates their history through a calendar, making time the primary dimension for exploration.

A large grandfather clock whose internal gears are stamped with location pins and date formats. The swinging pendulum is knocking away generic social media like buttons, illustrating the focus on chronology over algorithmic feeds.
Travel-Story anchors data in time and geography, explicitly rejecting algorithmic sorting mechanisms.

The Security Paradox

Reviewing the codebase reveals a fascinating mix of mature architectural decisions and early-stage open-source realities. On one hand, the authentication system is robust. The application issues JSON Web Tokens with a strict 72-hour expiration window. Passwords are salted and hashed using bcrypt with a factor of 10.

On the other hand, a dive into the commit history reveals a classic rite of passage. Early commits included a live config.json and an unmasked .env file. While the `.gitignore` has since been updated, this paradox highlights the learning curve inherent in building public, self-contained applications.

The Monorepo Blueprint

Zooming out, Travel-Story utilizes a pure monorepo structure. Both the `/frontend` and `/backend` directories live side-by-side within a single repository. This approach drastically lowers the barrier to entry for deployment.

Modern serverless stacks often require developers to manage multiple vendor accounts. A standard Next.js application might rely on Vercel for hosting, Supabase for the database, and AWS for image storage. Travel-Story can be deployed entirely on a single cheap Virtual Private Server. It trades infinite horizontal scalability for absolute simplicity.

A split composition showing a sturdy wooden chest with organized files on the left, and a chaotic network of pneumatic tubes scattering papers into clouds on the right. This compares local MERN storage against distributed serverless architecture.
The tradeoff between self-contained local storage and distributed cloud architecture.
FeatureSelf-Contained MERN (Travel-Story)Modern Serverless (Next.js + BaaS)
Data LocalityLocal Disk (Multer)Distributed Edge (S3/Cloudinary)
DeployabilitySingle VPS (DigitalOcean/Linode)Multi-Vendor (Vercel + Supabase)
ScalingVertical (Larger hard drive)Horizontal (Stateless functions)
ComplexityLow (Single repository)High (API keys, CORS policies)