You are browsing as a guest. Sign up (or log in) to start making projects!

AidenHammy

@AidenHammy

Joined June 8th, 2026

  • 19Devlogs
  • 6Projects
  • 4Ships
  • 30Votes
Open comments for this post

1h 19m 10s logged

Devlog 2 - Tiny Progress is Still Progress


College has been eating up most of my time lately so I haven’t been able to work on Asterism as much as I’d like. Still, I’ve been squeezing in about 5–10 minutes whenever I can. It doesn’t sound like much but I keep telling myself that something is better than nothing. Hopefully that’s true in my case too. Most of the progress has been on the CSS. Nothing groundbreaking yet but it’s taking shape, I think..? It’s still very much a work in progress and honestly… I’m kind of figuring things out as I go. I’m not entirely sure where this project is heading aesthetically but I’m trusting the process. Sometimes you just have to keep building until everything starts clicking into place. That’s pretty much it for this devlog. I wish I had more exciting things to share but college has completely drained me. I’m absolutely exhausted and my brain has officially stopped producing coherent thoughts. Hopefully the next update will have more than just CSS tweaks and maybe even some NASA API magic (hopefully x2)

0
0
6
Open comments for this post
Reposted by @AidenHammy

50m 29s logged

So I added the base for the galerie.I just need to add a slideshow thing which is going to be a little hard because I already have 2 and I need to add the 2 buttons to switch between the images.I am giving my best to squeze in coding time but the graphics themselves take a lot of time.Thanks for reading!!!

2
1
242
Open comments for this post

2h 20m 13s logged

Devlog 1 - Getting something on the page

Renamed the project to Asterism mostly because I didn’t want to keep looking at “apod-site” in my file tree. I spent way longer than I expected just laying out the HTML. I kept going back and forth on whether to build the archive/logbook or wait until I actually need them and ended up just doing all of it upfront so I’m not restructuring divs later while also trying to debug JS. Not sure that was the right call, it means I have a full page of markup and literally none of it does anything YET


The JS side was easy actually. I wanted to just check the NASA API actually returns what I think it returns before touching the real page so I hacked together a quick fetch on a totally separate.

#datepicker/#app that isn’t even in my real HTML. I mean it previously did. And It worked, sort of. Proved the concept but now I have to go rip it out and rewire it to the actual elements. Also just noticed I left a require("jspdf") at the top of the file that I don’t even use. I must’ve grabbed it off some snippet while I was googling something else and forgot to delete it. That’s not going to work anyway since this is Vite/ES modules and not Node. I didn’t get to do styling at all beyond the reset so right now it’s just there. Black text on white, nothing scoped, no theme variables defined just yet

0
0
3
Ship

My personal site, it's built around a notebook metaphor instead of a standard portfolio layout. Grid paper background, hand-drawn margin annotations and a Marginalia section for things that don't fit under "projects". Built with HTML, CSS and a small amount of JavaScript (very small indeed). Full writeup of the process is in the devlog!

Try project → See source code →
Open comments for this post

2h 4m 21s logged

Devlog 4 - probably the last one before this ships


I keep telling myself this is close to done which is exactly what I said the last three times so take that with the appropriate amount of salt. But this time there’s a real reason to believe it. Most of what’s left is polish not decisions anymore.

what actually changed

The site went through more identities than I’d like to admit before landing on the notebook look. I tried a blueprint version, a PCB/circuit-board version, a GitHub-dark version. All of them looked fine. But none of them looked like it suited me, it was a very conflicting feeling. The notebook one stuck because it’s the only one where the metaphor does real work! grid paper, a spiral binding, margin notes with actual arrows pointing at the sentence that matters. It made sense in my head so I left it that way.


Once the theme was settled, most of the work was making it feel less templated and more like something a person actually wrote. Early drafts of the About section kept reusing the same few phrases without me noticing. Every project blurb ending on the same self-deprecating note. Once I caught it, I went back through line by line and cut the repeats until it actually sounded like me instead of me imitating myself. The newest piece is Marginalia. A small section for the stuff that doesn’t fit under “projects” because it’s not a project, it’s just what I’m reading right now; that could mean a design thinking book, German grammar drills, Meditations, my interest about semiconductors. It’s styled as loose index cards taped down at odd angles instead of a clean list on purpose. A tidy bulleted list would’ve looked like a resume section. This is supposed to look like stuff pinned to a corkboard because that’s closer to what it actually is. There’s a colophon now too, tucked at the very bottom. What I built it with, what it’s set in. Small thing but I like that it’s there.

why it’s taking this long

Two honest reasons, no dressing them up. College session started back up and coursework wins every time it competes with a side project for hours in a day. That’s not a complaint, it’s just the actual constraint. I can’t build fast on a hobby site when the thing paying for the degree needs the same brain. And I’ve just been tired. Just the ordinary physical exhaustion of stacking coursework on top of a project I care about where neither one gets the focus it deserves and both end up a little slower for it. Some nights the right call was closing the laptop instead of pushing out a section that would’ve needed redoing anyway.


Neither of those is a great excuse for a slow devlog cadence but they’re the true ones.


what’s actually left

Contact section still isn’t back in. dropped it a while ago, might need to rebuild it now that the rest of the layout has moved on. I do need suggestions and opinions for that. And there’s a couple of real bugs to clean up before this goes anywhere public. And then it’s done or at least done enough to stop calling it a work in progress

0
0
10
Open comments for this post

3h 15m 30s logged

Devlog 3

There are already enough portfolios on the internet. You know the ones with dark background, giant gradient blob, “Hi, I’m X” followed by twelve technology logos and a call-to-action that says “Let’s Connect.” They’re polished but they don’t really tell you anything about the person behind them. And I wanted something different. The idea slowly became a notebook. Not a perfect one, one that’s been carried around for a while. Grid paper, handwritten annotations, sticky notes, typewriter text, little arrows pointing at things that probably didn’t need explaining but got explained anyway


The About section became surprisingly personal. Instead of listing hobbies, I wrote about why I enjoy electronics, why medieval engineering fascinates me and why I keep pulling things apart until I understand how they work. It feels much more honest than anything else. Marginalia is probably my favorite section so far. It’s exactly what the name suggests! the things I’m currently reading, learning or obsessing over. German grammar drills, Meditations, semiconductors.. they’re all snapshots of whatever has my attention at the moment. The little sticky notes scattered around the page make it feel like someone actually uses this notebook instead of simply displaying it. I also hid a small easter egg in the navigation. Every personal website deserves at least one thing that exists purely because it made its creator smile.


This devlog ended up being less about adding new features and more about polishing what was already there. Most of the time went into fixing CSS quirks, adjusting spacing, repositioning elements and making everything feel a little more cohesive. None of the changes were particularly flashy on their own but together they made the site feel much closer to the notebook aesthetic I had in mind. It’s one of those sessions where a dozen tiny tweaks ended up making a much bigger difference than a single new feature ever could

0
0
8
Open comments for this post

2h 18m 13s logged

Devlog 2


Getting the About section written took longer than I expected. Because it’s surprisingly difficult to write about yourself without sounding like you’re trying to impress someone. I rewrote the same paragraphs more times than I’d like to admit, slowly replacing things that sounded good with things that actually felt like me. The Projects section had a different problem. Turns out writing code is easier than writing about the code you’ve already written. Summarizing months of work into a few sentences, choosing screenshots, deciding what to leave out and figuring out what someone would actually find interesting is its own little design challenge. The biggest change, though, ended up being the handwritten notes


At first, the page looked like every other portfolio I’d seen. Project title, description, repository link, repeat. It worked but it didn’t feel like my notebook. The little margin notes, project statuses and honest comments about what went well (or didn’t) gave each project a bit of personality. Ironically, those tiny annotations took longer to write than some of the summaries. Maybe building a portfolio isn’t really about showing everything you’ve made

0
0
4
Open comments for this post

3h 9m 46s logged

Devlog 1: Trial and error will be the end of me


This page took almost three hours and somehow none of that time was spent writing code. I mean- it was.. BUT YOU GET MY POINT. The hardest part wasn’t building it. It was deciding what it should even look like. I went through idea after idea, scrapped most of them then spent way too long trying to imagine the layout in my head. How much space should there be between sections? Is this too empty? Too crowded?


The funny part is that I wanted this site to feel like one of my real notebooks. Except my real notebooks look like they survived a natural disaster. They’re full of arrows pointing nowhere, thoughts squeezed into the margins, things crossed out three times and random ideas that only make sense because I wrote them. Turns out translating that into a website without making it look completely chaotic is… surprisingly DIFFICULT! GRRAAHH


Every project reminds me of the same thing. Starting is the hardest part. Finding a direction, committing to a design and figuring out the layout and spacing always takes me longer than writing the code itself. Eventually something clicks. Until then, it’s mostly moving things around, staring at them, moving them back and pretending it’s part of the process, ay i mean it kinda IS part of the process! ANYWAYS, as i was saying- trial and error is genuinely going to be the end of me one day.

0
0
5
Ship

AuriaOS is a browser-based desktop environment built entirely with vanilla HTML, CSS and JavaScript. It features a complete window manager with dragging, resizing, edge snapping, maximizing and minimizing alongside a Start Menu with live search, pinning, recent apps and full keyboard navigation. It also includes a functional Terminal where commands like theme, pin, darkmode and shutdown interact with the operating system itself. Settings, notes, pinned apps and recent activity are all persisted using localStorage.

The biggest challenge wasn't adding features. It was making them work together reliably. I spent a lot of time debugging Javascript, tracing unexpected behaviour and reworking functions until interactions felt consistent across the entire desktop. I also kept the scope manageable by building the OS incrementally. I treated each subsystem as its own milestone instead of trying to create everything at once.

One of the parts I'm happiest with is that AuriaOS behaves like a single, connected system rather than a collection of isolated apps. The Start Menu, Settings and Terminal all share the same state so changes made in one place are reflected everywhere else. The terminal is fully functional too! It isn't just a visual prop.

Current apps -> Fully functional (Mentioned below)

Window Manager, Start Menu, Settings, Notepad, Terminal

Placeholder apps

Browser, Calculator, Mood Lamp, Fortune Cookie

  • 1 devlog
  • 3h
  • 9.22x multiplier
  • 29 Stardust
Try project → See source code →
Open comments for this post

3h 10m 2s logged

Devlog: Reworking AuriaOS’s Visual Identity

I thought AuriaOS was ready to ship. The window manager was working, apps launched, windows could be dragged, resized, minimized and restored. And the logic was solid.

Then the project got flagged as AI-generated, well I wouldn’t say AI-generated but maybe traits similar to that of one. It wasn’t because of the code but because of the UI.

Looking back, I understood why. The dark navy background, teal accents, frosted glass, soft glows and identical rounded corners looked a lot like the visual style that’s become common in AI-generated interface concepts. Those chosen elements together, they unintentionally resembled that aesthetic.

So I decided to redesign the visual system without touching the underlying functionality!

Redesigning the UI

The HTML and Javascript mostly stayed the same but most of the CSS was reworked.

  • Replaced the glassy navy and teal theme with a warmer ink and brass palette
  • Split the single border radius into multiple sizes so controls, windows and tiles each have their own geometry
  • Removed glow-heavy styling in favor of flat panels, subtle borders and offset shadows
  • Simplified typography by using JetBrains Mono for the interface with Fraunces reserved for the Start menu greeting
  • Replaced decorative gradients with a subtle SVG grain texture
  • Added small details like a window seal, custom text selection and distinct hover treatments across different UI regions
  • Swapped macOS-style traffic-light controls for simpler outlined window buttons

My goal was simple, it wasn’t to make the UI less polished, it was to give it a clearer identity.


Bugs I Found Along the Way

Rewriting and going through every CSS rule also uncovered a few real bugs


Broken resize handles

Some resize handle selectors accidentally used descendant selectors instead of grouped selectors so several resize directions silently stopped working


Invisible desktop

Adding overflow: hidden exposed another issue: #desktop never had an explicit height. Because every child was absolutely positioned, the container collapsed to zero height and clipped everything inside it. Restoring width: 100% and height: 100% fixed it immediately


A backwards theme toggle

The old “Dark Mode” toggle now made the already-dark interface lighter so i renamed the user-facing option to Light Mode while keeping the internal setting unchanged


Looking Back

Getting the project flagged was frustrating but it pushed me to reconsider the design instead of just accepting my first version. The redesign gave AuriaOS a stronger visual identity and the careful review of the stylesheet ended up revealing several bugs that had gone unnoticed during the rewrite. In the end, the project became better both visually and technically

0
0
4
Open comments for this post
Reposted by @AidenHammy

7h 37m 59s logged

POLITICS!! + Debugging Hell v2

I mean I guess it is? Not too sure.

Event Manager completely overhauled. Double events now no longer have the chance of repeating the same event.

Created a new GameEffects script which just takes a bunch of simple code away from EventManager and plays the basic functions such as the “tax revenue increases” which you see below.

This was quite a headache to create, and I severely underestimated how much time this would take. I have 2 extra nested classes inside of EventManager for Political Question and Political Scenario.

[... inside EventManager.cs ...]
    public class PoliticalQuestion
    {
        public string Question;
        public TaskCompletionSource<bool> TaskCompletionSource = new TaskCompletionSource<bool>();
        public Action onAccept;

        public PoliticalQuestion(string question, Action onAccept)
        {
            Question = question;
            this.onAccept = onAccept;
        }
    }

    public class PoliticalScenario
    {
        public string description;
        public Action runnable;

        public PoliticalScenario(string featureDescription, Action functionality)
        {
            description = featureDescription;
            runnable = functionality;
        }
    }

    [Header("Political Question Variables")]
    public List<PoliticalQuestion> PendingQuestions = new List<PoliticalQuestion>();
    public event Action onQueueChanged;

    private PoliticalScenario[] goodFeatures;

    private PoliticalScenario[] badFeatures;

The political question is sent off to the UI manager, which displays it as shown below. Then it handles user input pressing Y/Enter or N/Esc to accept the user choice, and returns it back to the Event Manager. Seems simple enough, yet there are many ways to do it but I think that the above implementation works the best out of all the ones that I tried. I attempted to use Game Manager as a middleman but that did not work out - so I resorted to passing an entire class.

The political scenario allows for the string to actually do something, so that the game knows what to process and what the user agreed to without creating a bunch of variables, and can allow for stacked political question events which is nice.

Game’s looking really neat, and the multipliers and stuff can make the game go very crazy very quickly.

Too much of a good thing is a bad thing!!

Debugged the entire system for like a solid 3 hours it was actually bad.

Came first in the UK tho!! I’m back after those 6 exams are done.

Yes I know the UI looks pretty bad but it’s good enough for pre-beta testing.

Oh yeah, speaking of UI everything is more bold. Figured out how to do that.

5
3
589
Ship Changes requested

AuriaOS is a browser-based web OS built entirely with vanilla HTML, CSS and JavaScript. It includes a full window manager (drag, resize, edge snapping, maximize), a Start Menu with live search, pinning, recent apps and keyboard navigation, plus a Terminal where commands like theme, pin, darkmode and shutdown actually control the OS. Settings, notes, pinned apps and recent activity all persist through localStorage.

The hardest part wasn't writing new features. It was debugging them. The JavaScript logic itself was just as challenging. I spent a lot of time debugging, reworking functions and figuring out why seemingly correct code behaved unexpectedly. I got stuck plenty of times but I decided to stick with it until everything finally clicked. Keeping the project's scope under control was another challenge so I broke large features into smaller phases instead of trying to build an entire desktop at once.

I'm proud that AuriaOS feels like one coherent system instead of separate features glued together. The Start Menu, Settings and Terminal all share the same underlying state so changing something in one place updates the rest of the desktop automatically. I'm also proud that the Terminal is genuinely functional rather than decorative.

The window manager, Start Menu, Settings, Notepad and Terminal are fully functional. Browser, Calculator, Mood Lamp and Fortune Cookie are still placeholder apps.

Things worth trying:

Drag a window to a screen edge to snap it
Open the Start Menu and use "/" to search or navigate entirely with the keyboard
Right-click an app to pin or unpin it
Open Terminal and run help then try pin calculator or theme #4ecdc4
Refresh the page to verify that settings, notes and pinned apps persist

Try project → See source code →
Open comments for this post

2h 9m 17s logged

Devlog 5


Picked up right where Devlog 4 left off. It was finally time to touch something nobody had looked at since day one, the Terminal. Before any of that though, I had a genuinely interesting detour into why I can’t just load real websites in an iframe. It turns out most sites send headers specifically designed to stop other pages from embedding them. That’s also the real secret behind those slick “browser inside a browser” demos we sometimes see online. They’re either fully staged or quietly running an actual browser on a server somewhere and just streaming a picture of it back to you, good to know. Also good to know I’m not building a server anytime soon. Future Aiden can deal with that one… if he ever does.


The Terminal ended up being the most satisfying thing I’ve built so far. Real command parsing, arrow keys cycling through history and commands that genuinely do things instead of just printing text back at you. The command pin calculator actually pins an app. theme #ff6b6b actually repaints the whole OS live. It’s one of those features that finally makes the desktop feel interactive rather than just clickable


And then, almost immediately, the most expected yet unexpected bug. I’d spent all that time getting the commands working, the history system behaving and everything feeling right.. only to forget the single line that actually connects the Terminal to its window when it opens. Fully built but completely silent because of one missing function call


I closed it out by fixing a bug that’s been sitting in plain sight since the very first day of this project. Maximizing a window always left a thin strip of empty space hovering just above the taskbar because the math was quietly subtracting the taskbar’s height twice instead of once


Hopefully my last devlog before shipping…
..for now
sigh…

0
0
6
Open comments for this post

8h 9m logged

Devlog 4 - The Start Menu Ate My Week


I js wanted to give the start menu some real attention instead of leaving it as a sad little list forever. I did NOT expect that to become the biggest sprint of the whole project but here we are… Built a proper pin/unpin system. My first version was a bit problematic so I sat with it for a while then rebuilt it the right way with an actual right-click context menu and everything. It felt genuinely satisfying once it finally clicked. Then I somehow convinced myself to add six more features to give the start menu a new life: greeting header, search bar, pinned grid, recent activity, system widgets and a whole user profile footer. Small moments of panic…? Definitely.. then I broke it into phases so I didn’t drown trying to build an entire desktop in one sitting.


What nobody tells you about “just redesign the start menu” is how many times you’ll open the same file and stare at the same fifteen lines wondering why they look right and behave wrong. Trial and error ate most of my time which is fair enough. I also gave every icon its own little color badge, wired up a real “/” keyboard shortcut to match the hint I’d put in the search bar then made the whole thing Tab-and-Enter navigable since none of it was there before. Every “small fix” somehow turned into reopening three different files and rechecking things I was already convinced were correct which… more often than not, they weren’t. But that part actually felt rewarding. Little by little, the menu finally started feeling alive.


And then, the bugs… I found out my own Start button was secretly broken, well… not heartbroken like me, at least. Clicking it did nothing at all because an old line of code was quietly fighting a newer one inside the same click handler. THAT took way TOO long to spot. The sneakiest ones weren’t even logic bugs.. a single missing dash in a CSS variable. A class name one word off from the real HTML. Completely invisible unless you go hunting line by line, just quietly doing nothing the whole time.


The JavaScript is by far the most nerve-wracking, head-splitting experience ever. Absolute horror. I don’t wanna touch that file ever again. My eyes are bloodshot. The amount of time I spent just staring at the code, hunting down errors one by one is honestly concerning..


The menu actually works now, start to finish. Search, pinning, keyboard navigation and all. It cost way more blood than a start menu has any right to. Genuinely proud of this one precisely because of how much it fought back. Terminal’s turn next. And it should be VERY afraid.


Note: Snuck localStorage into the project too! Turns out users generally prefer their settings, notes and pinned apps to exist for longer than five seconds. Weird bunch.

0
0
5
Open comments for this post

2h 20m 41s logged

Devlog 3 - Window Manager Upgrade


Came back to the window manager because it was bugging me. Windows could be dragged anywhere including straight off the edge of the screen with no way to get them back short of refreshing. No resizing at all. No snapping. All the stuff that makes an OS feel like an OS instead of a box you can shove around. So this was the sprint where I tried to fix that and it took way longer than I thought, mostly because of bugs I caused myself.


First up was resize handles, eight invisible strips around each window’s edges and corners so you can grab any side and resize from there. First try did nothing. Not an error, just nothing. Turned out my windows have overflow: hidden for the rounded corners and I’d put the handles slightly outside the window’s box so the browser was just clipping them out of existence along with their mouse events. Moved them inside the edge instead and they worked.


Then, while retyping some of it by hand, I wrote .querySelectorAll(".resize-handle".forEach(...)) instead of .querySelectorAll(".resize-handle").forEach(...). One parenthesis in the wrong spot and I was calling .forEach on a plain string instead of on the actual list of elements. Broke resizing AND window-opening at the same time since the error happened before the window even got added to the page.


Bounds clamping was a smaller fix but it’s the one I’m most relieved about. Windows can hang halfway off an edge now but they physically can’t disappear off-screen anymore, there’s always a grabbable strip of titlebar left no matter how far you drag. And then snapping, the one I was most excited for. Drag a window to the left or right edge and a ghost preview shows up where it’ll land, let go and it snaps into half the screen. Drag to the top and it maximizes. I almost skipped the detail where dragging a snapped window away from the edge pops it back to its old size first instead of just dragging the half-screen shape around looking weird but glad I didn’t, that’s the part that actually sells it.


Then dragging itself went completely haywire right after snapping started working, windows flying way faster than my mouse was moving, snapping in the wrong spots, clamping not holding. Assumed snapping broke it. It hadn’t. Found a line where I was adding the drag delta twice, once to calculate the clamped position and then again by accident when actually setting it.


Double-clicking a titlebar now maximizes/restores too, it felt wrong not having that once snapping existed. Window manager finally feels solid instead of held together with tape. Small wins matter! even the ones that take an embarrassingly long time to find.

0
0
13
Open comments for this post

3h 2m 51s logged

Devlog 2 — Things Finally Started Moving


Picked this back up today and this was basically the point where I started adding JavaScript and making things actually work. Up until now everything was just static UI. At first, I was building app content directly inside JavaScript strings… which worked but got messy really fast. The big breakthrough was moving all of that into proper HTML <template> tags instead. Sounds small but it made the code way easier to manage. Don’t have to squint at quotation marks trying to understand layout and styles.


Got the window manager fully working! open, close, minimize, maximize, drag around. Each window now gets a taskbar button that reflects its state. Clicking a minimized window restores it, clicking an active one minimizes it. The Start menu can launch apps now and desktop icons work too. You can double-click an icon to open an app which is a small thing but makes it feel a lot more real. Also wired up the Settings panel. Toggles switch between ON/OFF, accent colors update the theme live and dark mode works (kind of a hack using CSS filters but it works). The Apps folder opens in its own window and can launch other apps from inside it. It’s all small features but they’re finally connected.


Spent way too long debugging why desktop icons weren’t responding. Turned out to be a typo in a template ID (“windows-template” vs “window-template”) combined with the script running before the DOM loaded. Very classic… huh? Wrapped everything in DOMContentLoaded and double-checked all IDs after that. Most of the apps (Browser, Terminal, Calculator, Mood Lamp, Fortune Cookie) are still just placeholders with static content. But the system around them feels solid now. Next step is making at least one of them actually do something interesting.. probably either a fake-command Terminal or a Mood Lamp with real color interaction.

Also: the Start button didn’t even have an icon before. Just an empty button sitting there. Fixed that. Small wins matter!

0
0
15
Open comments for this post

5h 44m 18s logged

Devlog 1 — Starting Somewhere

Started working on AuriaOS today. Honestly, it’s pretty rough right now. I didn’t really try to build anything complex yet. Mostly just figuring out how to structure everything. Got a basic desktop layout in place with some icons (browser, terminal, notes, etc.), a taskbar and a start menu. None of it actually does much yet.

Spent a lot more time than expected just on CSS. Things like spacing, colors, trying to make it not look completely off. I set up a dark theme with variables so I don’t have to keep rewriting stuff later, which feels like it’ll help. Also added a window template system so I can reuse it when I actually start making apps. Right now it’s just sitting there but I think it’ll make things easier later.

There’s a settings page UI and an apps folder too but they’re basically just placeholders. Buttons don’t really do anything yet. Overall, it doesn’t look like much for a full day but I guess this is just the setup phase. Still trying to understand how everything should fit together.

0
0
19
Ship

## What did you make?

A CLI calculator built from scratch in Node.js. Not just a basic one, it runs as a full REPL in your terminal, supports both command-driven operations (`add 2 3`, `sin 90`) and free-form math expressions (`2 + 3 * 4`, `sin(90) + 10`), remembers your last result with `ans`, logs every calculation to a history file with timestamps and validates inputs with actual helpful error messages.

Over the last week I also ported the whole thing to run in the browser using xterm.js so you can try it live without installing anything.

---

## What was challenging?

Honestly, most of it at some point.

The expression evaluator was probably the hardest part. Using `Function()` to evaluate raw user input feels powerful but also kind of risky and making it fail gracefully without breaking anything took a while to get right. The `ans` memory system was tricky too because replacing it correctly across both commands and expressions without accidentally mangling other words required careful regex work. The browser port was a whole different kind of hard. I didn't realize how much Node.js was doing for me silently. `readline` alone handles an entire input loop that I had to rebuild character by character in xterm.js.

---

## What are you proud of?

A few things:

- The **validation architecture** — argument counts, type checks, domain-specific errors (division by zero, negative square roots, log of non-positives) all cleanly separated from the actual math logic

- The **`ans` memory system** — being able to chain `pow 2 8` → `add ans 100` → `ans / 2` makes it feel like a real calculator

- The **expression evaluator** — typing `sin(90) + 10` directly and getting `11` feels satisfying every time

- The **history system** — timestamped, persistent, filterable with `history [n]`

- The fact that the browser demo runs the exact same logic as the CLI — `calc.js` was never touched, the port lives in a separate file

This was built step by step over 6 devlogs in about a week. I'm still a beginner and it's not perfect but it genuinely feels like something I made rather than something I just followed a tutorial for.

---

## What should people know so they can test your project?

The easiest way is the live browser demo — no install, just open the link:

🔗 https://cli-calculator-five.vercel.app/

Try these to get a feel for it:

```
help
add 2 3
pow 2 8
add ans 100
sin(90) + 10
2 + 3 * 4
history
```

If you want to run it locally instead:

```bash
git clone https://github.com/AidenHammy/cli-calculator.git
cd cli-calculator
npm install
node src/calc.js
```

  • 6 devlogs
  • 14h
  • 13.37x multiplier
  • 190 Stardust
Try project → See source code →
Open comments for this post

1h 43m 29s logged

Devlog 6 — Taking the CLI to the Browser


Biggest struggle

The hardest part wasn’t writing new features. It was translating existing ones into a completely different environment.

The original CLI felt natural because Node.js gives you everything: file system, stdin/stdout, process control. The browser gives you none of that. Every tool I had been relying on: readline, fs, chalk, console.log even process either doesn’t exist or behaves differently in a browser context.

The trickiest translation was the input loop. readline handles line buffering automatically, you just wait for the user to press Enter and get the full line back. With xterm.js, you get one raw character at a time via onData.

The other catch was the expression evaluator. After porting everything over, sin(90) + 10 was returning "Invalid command or expression" because the Function() scope didn’t know what sin was. The fix was straightforward once I understood the cause, exposing the math functions as local constants inside the Function() string but it was a good reminder that a working feature in one environment isn’t automatically working in another.


What changed in this version

New files

  • src/calc-demo.js:- full browser port of calc.js using xterm.js
  • main.js:- entry point: boots xterm, loads the fit addon, calls initCalc(term)
  • index.html:- static shell with topbar, terminal mount and statusbar
  • style.css:- dark terminal theme built around a monospace font stack and a single green accent

Key substitutions made

Node.js (calc.js) Browser (calc-demo.js) readline xterm.js onData + manual buffer chalk ANSI escape codes fs / history.txt localStorage console.log term.write() via print() process.exit location.reload()

calc.js is untouched. The original CLI still runs exactly as before with node src/calc.js. The browser build is a separate port not a replacement.


Current features

  • Everything from Devlog 5, now running in the browser
  • Live deployment on Vercel. No install, no terminal, just a URL
  • Terminal emulator UI with topbar, statusbar and live clock
  • Full xterm.js input handling: backspace, local echo, line buffering
  • History persisted in localStorage across page reloads
  • Expression evaluator now supports sin(90) + 10, sqrt(144), abs(-5) etc. directly
  • cls clears the xterm screen properly using escape sequences
  • exit reloads the page

Reflection

Devlog 5 ended with “maybe create a simple web version for easier demo access” as a future idea. This devlog is that idea, actually shipped.

What surprised me most was how much invisible work Node.js was doing. You write readline and it just works but behind it is a whole input loop, line buffering, echo management and terminal control that you never think about. Doing it manually in xterm.js made all of that visible which was frustrating at first but genuinely useful to understand.

The project now has two lives: a proper Node.js CLI tool and a browser demo that looks and feels identical. That separation, keeping calc.js untouched and building the browser port as a parallel file felt like the right architectural call. One doesn’t compromise the other.

It’s also the first time something I built has a real public URL.


0
0
3
Open comments for this post

4h 38m 42s logged

Devlog 5 — Expressions, Memory and a Real “Calculator Feel”


What I learned:

  • How to evaluate user input dynamically using Function() (and why it needs to be handled carefully)
  • How to replace parts of user input using regex.
  • How to structure commands when the number of arguments isn’t always fixed (min/max validation)
  • How small UX details (like colors using chalk) make a big difference in usability
  • How to maintain state across a REPL session
  • How to design a fallback system where unknown commands are treated as expressions

Biggest struggle:

This one was definitely more complex than the previous days.

The hardest part was adding expression evaluation.
Using something like Function() to evaluate user input felt powerful but also risky and confusing at first. Making sure it doesn’t break on invalid input and handling errors properly took some time. Another tricky part was implementing a feature (ans) that lets you reuse the previous result in new calculations. Ensuring it worked consistently across both commands and expressions required careful handling of user input. Replacing it correctly in user input without breaking other words or expressions required using regex carefully.

Also, as the number of commands grew, validation started getting messy. Switching to a min/max argument system helped but it took a bit of thinking to get right. This stage felt less like “just coding” and more like designing how the calculator should behave.


Current features:

  • Full REPL-based interactive CLI

  • Support for both commands and direct expressions:

    add 2 3
    2 + 3 * 4
    
  • ans keyword to reuse the previous result

  • Expanded math operations:

    • Trigonometry (sin, cos, tan)
    • Logarithms (ln, log)
    • Factorial (fact)
    • Rounding (round, ceil, floor)
    • Absolute value (abs)
  • Improved validation with flexible argument handling (min/max support)

  • Persistent history with timestamps

  • Optional history limit (history n)

  • Colored and structured output using chalk

  • Better error handling for invalid commands and expressions


Next steps:

  • Improve expression parsing (support more complex cases safely)
  • Possibly replace Function() with a safer custom parser
  • Add command chaining or multi-step calculations
  • Improve UI further (custom prompt, better formatting)
  • Maybe create a simple web version for easier demo access

Reflection:

This version feels like a big step forward. Before, the calculator was command-based and structured. Now it feels much more natural and flexible, especially with expressions and the ans feature. It’s starting to behave like an actual calculator instead of just a program that runs specific commands.


At the same time, the complexity is definitely increasing. It’s getting harder to manage everything cleanly which makes me realize how important structure and planning are as projects grow. It’s not perfect but it finally feels like something I could actually use. Not just something I built to learn.

0
0
2
Loading more…

Followers

Loading…