DEV Community

Cover image for AFTERHOURS: A Little Archive for the Things We Can't Quite Let Go
Mehroof Saba
Mehroof Saba

Posted on

AFTERHOURS: A Little Archive for the Things We Can't Quite Let Go

Hacktoberfest Open-Source AI Challenge: Ghost in the Machine Submission 👻🌼

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

Some things don't need to be sent, solved, or understood. They just need somewhere to stay.

What I Built

I built AFTERHOURS, a private, candlelit archive for memories, unfinished thoughts, and letters that were never sent.

The idea started with something simple: sometimes you want to write something down without turning it into a task, sharing it with someone, or being told what it means. You might have a memory you don't want to lose, a thought you can't categorise, or a letter that was never meant to leave your hands.

I wanted to build a space for those things.

AFTERHOURS is designed as an antique archive with three rooms:

    1. The Memory Cabinet - a place for memories worth keeping, organised into drawers, tags, dates, and moods.
    1. The Lost & Found - a home for fragments of thought that don't quite belong anywhere yet. Related fragments can be linked, and shared words create little local echoes between entries.
    1. The Unsent Archive - a quiet place for letters you never intend to send, complete with wax seals and drafts that stay yours.

Each room belongs to the same little world: dark wine tones, aged paper, candlelight, and the feeling of finding an old letter after midnight.

But the atmosphere is only half the project.

AFTERHOURS also has a local AI writing companion. It can help reshape memories into literary passages or poems, offer alternative versions of unsent letters, and provide reflective prompts for fragments of thought.

The important part is that it doesn't get to decide what your words mean. Its output is a suggestion, not a verdict.

I chose the Ghost in the Machine theme through the idea of keeping the past close. The ghost isn't a supernatural character hiding in the interface. It's the trace of something that happened, the words we leave behind, and the strange way a piece of writing can make an old feeling present again.

AFTERHOURS is my attempt to give those traces a home

Demo

Live application: https://afterhours-cszu.onrender.com/

Code

Source code: https://github.com/mehroofsaba/AfterHours

The repository includes the React application, its three archive rooms, local database and archive import/export logic, AI client and worker, model configuration, prompts, and the Render deployment configuration.

How I Built It

The application is built with React 19, Vite, Tailwind CSS 4, Motion, React Router, IndexedDB, and Lucide.

The AI layer uses Transformers.js, allowing supported open-weight language models to run directly in the browser rather than relying on a hosted inference API.

Inference runs in a Web Worker. The application can use WebGPU when supported by the selected model and environment, with WebAssembly available for compatible configurations.

The model options are configured in src/lib/models.js. They include small instruction-tuned models such as SmolLM2 and Qwen2.5, with the exact experience depending on the selected model and the user's hardware.

The AI is integrated into the actual writing experience rather than being a decorative chatbot. It can generate alternative versions of memories and letters, and help users explore fragments through prompts and themes. Users can compare suggestions with their original writing and decide what, if anything, to keep.

The rest of the archive uses IndexedDB to store memories, fragments, letters, custom drawers, and settings in the current browser profile. Export and import functionality provides a way to back up and restore an archive.

There were trade-offs. Small models can be slow on some devices, produce generic writing, or drift from the original meaning. The first AI operation can also require a substantial download. That is why the AI remains optional and its output stays editable.

Why Does Open Innovation Matter?

For a project built around personal writing, where the AI runs matters almost as much as what it produces.

A conventional hosted AI API would make it easy to send text to a remote service and receive a response. But I didn't want a private archive to depend on sending every unfinished thought or unsent letter to a remote inference endpoint.

Using open-weight models with browser-based inference gave me another way to approach the problem.

The writing can stay on the user's device during AI operations. The app does not need a separate inference server or an API key for its writing features. Model options can be changed in the code, prompts can be inspected and improved, and the behaviour can be adapted without rebuilding the entire product around one closed AI provider.

Open innovation also makes the limitations visible. Model choice, inference speed, prompt design, runtime support, and download size are things I can examine and improve instead of treating the AI as an invisible service.

That doesn't mean the application is entirely offline. Model weights and runtime assets may need to be downloaded, and the interface loads external fonts. Browser storage also comes with real limitations. Local inference is a privacy-oriented design choice, not a promise that no network requests ever happen.

For me, the value of open AI is the ability to make deliberate choices about the technology behind a personal tool — and to let other people inspect, learn from, and improve those choices.

The Spirit of It

keep coming back to the idea of an unsent letter.

There is something unusual about writing words you never intend to deliver. You can be honest without having to decide what happens next. You can revisit a memory without needing to turn it into a lesson. You can leave a thought unfinished without treating it as a failure.

I wanted AFTERHOURS to feel like opening a drawer in an old room and finding something you had forgotten you kept.

The AI doesn't need to impersonate a ghost or pretend to know the person behind the writing. It can simply offer another way to phrase a sentence, a different shape for a memory, or a prompt that helps someone continue writing.

The human part stays human.

And perhaps that's the nicest interpretation of Ghost in the Machine I could find: not a machine pretending to have a soul, but a machine helping us preserve the traces of our own.

Prize Categories

Best Use of Render - if the final application is deployed on Render as planned and the submission meets the category requirements.

Top comments (0)