July 13, 2026 · Experiments
Building Auranite: How I Vibe Coded a Map of the Unexplained
My side project Auranite started with a simple idea: what if unexplained events had a real place to live?
Not another endless forum thread. Not a pile of disconnected videos. I wanted a world map where a strange light over Denver, a historical UFO case, a haunting, or a cryptid report could be explored by location, time, category, evidence, and context.
That idea became AURANITE — the world's map of unexplained events.
The visible map was the fun part. The real build was everything underneath it: accounts, sessions, reports, moderation, media, structured event data, filtering, and the line between a community submission and a public record.
Starting with the Experience
I did not begin with a giant architecture diagram. I began with what a visitor should be able to do:
- Open a map and immediately see approved reports.
- Filter cases by category, report type, location, and time.
- Select a marker and understand the event without leaving the map.
- Open a full report when the summary is not enough.
- Create an account and submit a new event.
- Trust that a new submission will be reviewed before it becomes public.
That list became the spine of the project. AI helped me turn each behavior into a smaller implementation problem, but I kept making the product decisions. That is the useful version of vibe coding: the model can generate a route or refactor a form, but it cannot decide what the community should feel like.
The Stack: Direct, Understandable, and Mine
Auranite uses a server-rendered PHP application behind Apache. I liked this approach because every public page could arrive as useful HTML instead of waiting for a large client application to boot. It also kept authentication, permissions, and report rendering close to the server-side rules that protect them.
The browser still has plenty to do. The Explore experience uses Leaflet with OpenStreetMap tiles. JavaScript handles markers, popups, filters, location search, geolocation, and the desktop/mobile interaction differences.
The boundary between browser and backend is deliberately narrow. The map requests approved event data from a JSON endpoint, /api/events.php. The backend decides what is public; the frontend decides how to display it. That separation matters. Hiding an unapproved report with CSS would not be moderation. Excluding it from the public API is.
Modeling an Event, Not Just Dropping a Pin
A map marker is only two coordinates. A useful report needs much more:
- A title and readable location
- Latitude and longitude
- Category and report type
- Event date and display-friendly time
- Description and evidence labels
- Media and witness counts
- Publication and featured status
- A stable URL for the full report
I also distinguish between community reports and historical archive cases. They share a map, but they do not make the same claim. A person describing something they witnessed is different from a curated record of an event from 1966. The backend preserves that distinction and the interface makes it visible with badges.
That data model made later features easier. Once categories and report types were structured instead of buried in prose, filters, themed marker colors, archive pages, featured cases, and statistics could all use the same source of truth.
Accounts, Sessions, and the Report Pipeline
Anonymous browsing should be easy. Publishing should be deliberate.
Auranite uses server-side sessions with secure, HTTP-only cookies and a SameSite policy. Account state changes what the server renders, and protected actions stay behind authentication.
The report workflow is not form → instant marker. It is closer to:
- A member creates a structured report.
- The backend validates and stores the submission.
- Uploaded media is associated with the event and organized into predictable paths.
- The report enters a review state.
- Only an approved event is returned by the public events endpoint and added to the archive.
That review step is part of the architecture, not just an admin habit. It protects the map from spam, unsafe media, accidental personal information, and reports that need clarification.
The Media Problem
Images make reports useful, but uploads are one of the fastest ways to turn a small site into a security and performance problem.
I built the media side as a pipeline rather than treating an upload as a random file. Event assets live in date- and event-based directories, and the public cards use generated thumbnails where available. That gives the application predictable URLs, lighter map cards, and a clean connection between a record and its media.
The important backend lesson was that an upload form is only the surface. The real feature includes validation, naming, storage, derived images, output escaping, access rules, and graceful fallbacks when no image exists.
What AI Actually Did
I used AI throughout the build for scaffolding, debugging, CSS iteration, PHP routes, data transformations, responsive behavior, and the repetitive work of keeping similar pages consistent.
The best results came when I gave the model constraints instead of vibes alone:
- Keep the application server-rendered.
- Preserve the current URL structure.
- Return only approved events from the public endpoint.
- Do not break mobile map controls.
- Escape user-controlled text.
- Test the logged-out and logged-in paths separately.
That changed the conversation from “make this cool” to “make this change without breaking the system.” Modern coding agents are much better at the second kind of prompt.
Where I Had to Stop Vibing and Engineer
The map can look finished long before the application is finished. The hard questions live underneath:
- Can a user access another user's draft?
- What happens when an upload is too large or malformed?
- Does a rejected report leak through an API response or sitemap?
- Are coordinates precise enough to create a privacy problem?
- Does every form enforce its rules on the server?
- Can a search engine find canonical event pages without indexing private routes?
Those are not reasons to avoid vibe coding. They are reasons to know when the vibe has reached the production boundary. At that boundary I slowed down, inspected requests, tested state changes, and treated AI output as a patch to review rather than an answer to trust.
What I Learned
Auranite taught me that a side project stops feeling small as soon as people can create accounts and contribute data. At that point you are building a system of trust.
The new generation of AI models can hold more of that system in context. They can trace a report from a form through validation to storage and back out through an API. They can run tests, inspect the rendered UI, and keep working through a checklist. That is a huge change from autocomplete.
But the most important decisions remained mine: what gets published, what the badges mean, how location privacy works, and what kind of archive Auranite should become.
That is the balance I want from vibe coding. The machine carries more of the implementation. I stay responsible for the product.
Explore the live project at Auranite.com.


