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

EpochOS

  • 24 Devlogs
  • 118 Total hours

EpochOS is a fully functional operating system built entirely with vanilla JavaScript, HTML, and CSS. It doesnt require any client side installations or anything and runs directly in your browser. Its features include a file explorer, a browser, a media player, many essential applications, lots of customisation, widgets, and an actual ecosystem that mimics a real operating system. It also has no backend so it's all run locally on your browser using the browser's localStorage. READ THE SHIP MESSAGE BEFORE TRYING IT OUT.

Ship #2

EpochOS is a fully functional operating system built entirely with vanilla JavaScript, HTML, and CSS. It doesnt require any client side installations or anything and runs directly in your browser. Its features include a file explorer, a browser, a media player, many essential applications, lots of customisation, widgets, and an actual ecosystem that mimics a real operating system. It also has no backend so it's all run locally on your browser using the browser's localStorage.

Some things you should know before you test this out:
Firstly, please don't finish rating this project until you experience all the features because there are many hidden features that might change your opinion. An example is easter eggs. I implemented many easter eggs which you must experience before voting because these easter eggs are very devloped. If you can't find them or are stuck on one of the easter eggs, read ARCHITECTURE.md and at the very bottom, i listed all the easter eggs so you can check them out.

In fact, read the ARCHITECTURE.md because it provides valuable info about many of the features in the OS and how they work so make sure to read that aswell

Secondly, this OS is not compatible with mobile or tablet devices and is optimized for desktop only. So please keep that in mind when you are testing it.

Thank you so much for testing this project and hope you enjoy it :)

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

21m 14s logged

WebOS 2 Devlog #21: Final Submission

Just did some final changes to the welcome text and am about to ship it

0
0
3
Open comments for this post

1h 0m 37s logged

WebOS 2 Devlog #20: Updated README.md and ARCHITECTURE.md + changed properties window

I just realised I had a properties window in the OS and that was quite outdated so I changed to include some new info like the Last Modified date which updates everytime the user saves something because i added a localStorage.setItem that saves the timestamp.

I also updated the README and ARCHITECTURE files to make them sound better and to add some additional info.

Anyway, this devlog is probably the last on for this project! Hope you enjoy :)

0
0
4
Open comments for this post

7h 48m 17s logged

WebOS 2 Devlog #19: README.md + ARCHITECTURE.md + additional customisation features

I’m in the final stages of the project and in this long session, I did many things. Firstly, I wrote a README.md with all the necessary stuff and i also made an ARCHITECTURE.md file which explains the nitty gritty insides of the WebOS so anyone can understand how the website works.

Other than that I added a couple of other stuff. Firstly, i realised that even though I have accents to customize the desktop, I don’t have a wallpaper gallery (except the nasa apod) which I found was quite necessary. At first, i coded my own wallpapers like a synthwave grid wallpaper, pinstripe wallpaper for the legace theme, a tranforming aurora wallpaper and like 3 more but after i coded them, they just looked so damn ugly. So i scratched the idea of me coding my own wallpapers and added three categories of wallpapers in the wallpaper dropdown with each category having three 4k wallpapers in them so every time you pick that category, you get a random wallpaper from the three.

I also added an about section in the settings which has a buttton that leads to the github page.

0
0
4
Open comments for this post

5h 22m 20s logged

WebOS 2 Devlog #18: Debugging session

I swear random bugs keep popping up no matter how much debugging I do. There’s always something that’s wrong or doesn’t work but that’s just how it is. In this session which was longer than expected, i fixed a lot of different bugs. Here is a summary of the changes i did:

  • I spent lots of time rewriting the mathematics for the desktop icon layout, and also changed the strict grid-snapping to free-form placement cus it felt it was quite annoying not to be able to place stuff on the desktop wherever you want. Unfortunately, it took too long and i abandoned the idea and just moved on without making any changes.

  • I also spent some time cleaning up the code and tried to optimizing the code.

Some other bugs I fixed include:

  • Desktop icons were randomly rearranging themselves every time a file was saved. I found out that the reason was that since the localStorage returns keys randomly, everytime i wrote sth to localStorage, the items were randomized so the ordier they appeared on the desktop changed. So i rewrote the logic to sort the stuff alphabetically before displaying.

  • The Notepad app was also blindly overwriting existing files with the same name. I fixed it by adding a localStorage query to intercept matching keys and to display an osConfirm dialog, forcing the user to explicitly authorize the overwrite.

  • The internal browser was throwing captchas all the time and failed to load error screens for blocked domains. Since Google aggressively blocks embeds and flags them as bot traffic, i changed the default browser to Bing, which was much better and i didn’t get captchas everytime i search somehting up

  • I also modified the system daemon engine so that it introduces itself when a user first view the OS.

  • The weather widget was pulling the location not from where the user was but rather where my ISP was routing my traffic through. So if i lived in a village and ISP routes my traffic through like New York, the weather that showed up was that of New York. To fix this, i swapped the logic to request exact hardware GPS coordinates via navigator.geolocation, while falling back to the IP routing API if the user denies the browser prompt. If the location is inaccurate the user can enable the location permission in the browser and the weather widget then shows the correct location.

  • The visualizer widget was working perfectly but i had the idea to add a text container above the bars which shows what the user is playing.

I made way way more changes but many of them conform to the easter eggs and mainly about the theme that gets unlocked (small spoiler there ;)) so i won’t really get too much into it.

0
0
3
Open comments for this post

10h 6m 26s logged

WebOS 2 Devlog #17: Media player + Audio spectrum widget implementation

It has been a massive coding session. And I barely managed to keep the time below 10 hours and I still went over it. But, on the bright side, the OS now has a fully functional, media player and an audio spectrum widget! In the media player, anyone can listen to radios, and lots of music. But the reason it took 10 hours is because implementing these stuff required facing some serious bugs-some of them for genuinely stupid mistakes-and rebuilding the audio engine the right way (you’ll see what I mean). Here is a breakdown of how these new features work, what went wrong, and some other stuff:

Overview of features

The Media Player:

The new Media Player is a audio application that routes requests to three distinct APIs to fetch music that the user can listen two:

  • Audius: This is a “decentralized music streaming platform for artists, labels, and fans.” And it’s free! I fetches some of the music from this API.

  • Radio-Browser: This is a platform that is, in a nutshell, Wikipedia for radios. I fetched thousands of live, global radio broadcasts using this API

  • Apple iTunes (Preview): This was a golden find because I didn’t know this existed (not for free anyway). This API pulls top hits and previews of music. Granted, it’s not full music tracks but the songs are much more famous and popular.

The Audio Spectrum Widget

To complement the player, I also added an Audio Spectrum visualizer. It uses the Web Audio API, or more specifically, its AudioContext and an AnalyserNode to get the frequency data from the audio element. That data is then mapped to an HTML5 element. Using requestAnimationFrame, I made it such that the spectrum repaints 40 individual frequency bars roughly 60 times a second, which creates the audio visualiser waveform thing.

Challenges

  • The Geolocation failure:

The OS was originally hardcoded to fetch radio stations from my address because I hardcoded that for testing purposes. But I stupidly forgot to remove that so when attempting to make this dynamic by using vpns I spent like 40 minutes trying to figure out why ut kept showing stations from my local area and not japan (where my VPN was connected to). And the reason for that is the hardcoded address I mentioned earlier. Moreover, some of the API queries were too specific, causing the media player to return empty for smaller regions like the Bahamas. To fix it i used the BigDataCloud API to quietly ping the user’s IP address, cache their true country code, and inject it into the API queries.

  • the broken audio spectrum:

Initially, the audio visualizer was completely blank. Even when fixed, the baseline would just disappear the second music started playing. The canvas drawing logic was also aggressively using clearRect to wipe the entire widget, which erased the idle state baseline. To fix it, I changed the baseline math so that the baseline sits firmly at the bottom of the widget. I also remade the drawing loop to explicitly redraw the baseline before checking the isPlaying state, so the frequency bars can work smoothly.

  • retro theme problems:

I completely forgot about the retro theme as i was just focused on building the player and the widget. So, in the end i had to make the stuff retro theme aswell. I encountered some problems there like some white on white text and some styles not applying which turned out to be because my dumbass brain mispelled the ids and classes

  • Oh, and I found some other big bugs. The dragging engine was hella laggy. Like the response time was like 3 seconds before it registered. I would go deeped but im abt to cross the 4000 character devlog word limit but in a nutshell I realised it was because the mousemove event listener was directly updating the inline CSS (style.left and style.top) on every single microscopic mouse movement so it was really laggy.
0
0
3
Open comments for this post

8h 30m 58s logged

WebOS 2 Devlog #16: Widget implementation + debugging

In this session, i made multiple changes to the OS to improve the overall UX. I had to pull another all nighter again 🥲. Here is what i changed:

Change 1: Debugging

  • Everytime i enabled the system daemon in the settngs, the entire os reloaded which was quite annoying so I ripped out the location.reload() in the Settings app. I also moved him to the body so he didn’t get trapped behind windows, because most of the time the daemon was floating behind windows and i couldnt really see him.

  • I also gave the Welcome screen a massive 9999999 z-index so the daemon would float behind it because my previous step was too effective and he was infront of every single screen including like the bootloading screen.

Challenges: I ran into z-index hell because I didn’t plan the stacking initially. He was either in the very front or at the very back and it was all a bit weird.

Change 2: Widget implementation

  • I initially wanted to implement sticky notes as a widget which was inspired my the mac sticky notes so i coded all of that in first but I realised i can take it a step further and code in multiple widgets.

Challenge: But the thing was i hardcoded the sticky notes widget so i had to recode everything and integrate all of the widgets at once

  • I added a simple analog clock widget
  • I added a calendar widget
  • I initially added a system monitor with like the ram and cpu data but the thing was due to the security restrictions, I can’t get the actualy live hardware data so it would have to be a simulation, which i didnt want so I replace the system monitor with a live weather widget which uses the BigDataCloud and Open-Meteo APIs to provide weather data.

Change 3:

Originally I had all hte widgets in the context menu on after the other but they looked like a list and a bit redundant. So i removed all then in the html file and added one ‘Add a widget…’ option which connects to a screen with all the widget options

0
0
3
Open comments for this post

6h 30m 46s logged

WebOS 2 Devlog #15: System Daemon implementation

To keep the users more engaged so even when they saw everythign, they would still spend more time doing stuff, I wanted to build something alive for the desktop environment that would interact with the user. So, instead of a standard app, I built a system daemon! If you dont know what that is, it is a digital pet that hangs out on your desktop and does random stuff. I dont hav ea name for him yet so ill just call him daemon for now. When he’s healthy, he flies around the screen and shouts random stuff at you.

But I didn’t want him to just be a visual gimmick. He interacts with the actual operating system itself and has states:

  • He is hungry: Because I previously built a drag-and-drop system for the File Explorer, I hooked him into it. You can drag actual text files or folders out of your explorer and drop them on his face. He will chew them up and literally delete them from the virtual hard drive (localStorage).

  • He has a digestive tract: I built a array for his stomach that records what he has last eaten. If he ate a file you actually needed, you can rapid-click his face 5 times. He will regurgitate the raw file data perfectly back onto your desktop.

  • He has boundaries: I ‘taught’ him to recognize core OS files. If you try to feed him Notepad.app or the System Settings, he will violently reject them and yell at you.

  • He has one more state but that relates to the easter egg so i wont provide any additional details in order to not spoil it

Oh, and i changed his appearance for the retro theme.

anywhat that’s all for this change. I didn’t get into the nitty gritty of how I built him because I am so excited to finish this project. Just a few more features and then I’m done.

0
0
2
Open comments for this post

7h 48m 23s logged

WebOS 2 Devlog #14: Easter Eggs Pt. 2

I am now done with making the easter eggs and in total i made 5 of them, which may seem less but some of them are really really complex and developed. I stayed up till 2am making these 😭. Out of these 5, three of them are simple easter eggs, one is more complex but still quite simple and the final one is essentialyl the absolut highlight. It is the reason why the easter egg section took me so long. I am not going to go into detail to avoid spoilers. Anyway i hope you have fun with the easter eggs :)
p.s the attached pic is a screen shot again cus i dont want to give spoilers

0
0
2
Open comments for this post

8h 48m 50s logged

WebOS 2 Devlog #13: Easter Eggs Pt. 1

I was looking forward to this a looooot. I’m not giving any spoilers whatsoever but I was so locked in tday and yesterday coding easter eggs into the OS. I added like 2 easter eggs (might seem less but trust me they’re very developed), one’s a very simple one but the other one is my favourite and is the reason this devlog took so long. It’s still not finished and im only lik halfway done w/ it but I’m not going to go into any details because it will spoil the fun but im sure you’ll enjoy it. Also, im not done with making easter eggs and i just made this devlog cus the time is almost 10hrs. I still have to finish the second easter egg and do more on top of that. The next one will hopefully be the final easter egg session (unless i get another absolute brainwave).

p.s to prevent spoilers, the attached pic is just a screenshot once again

0
0
3
Open comments for this post

3h 15m 5s logged

WebOS 2 Devlog #12: Debugging Session + retro theme redesign

In this session I started debugging the os and wow i found a lot of bugs. Im not going to get into them because it would take too long but some of them include how the bootloading sequence absolutely breaks if the user presses escape before the setup is finished because the cache isnt cleared properly so when the user gets the setup agian, he wont we able to configure some stuff like the password because the cache wasnt cleared properly.

I also redesigned the retro theme because it looked ugly because the accents i implemented in the modern theme appeared in the retro theme which didnt fit together. Moreover, some of the aspects of the retro theme, such as the top part of the web browser or the settings screen were just uncomfortable to look at. Changing the retro theme was such a pain because everytime i thought i fixed it, a new discrepancy appears and at one point after i fixed it, my retro-theme.css was so messy i couldnt be bothered to fix it so i just inputted the messy working version into gemini and it cleaned it up. Anyway that was all i changed this time. And I did more and more changes but many of them are small and it would take too long to explain in a devlog.
p.s. didnt know which pic to attach so its just a simple screenshot of the desktop.

0
0
3
Open comments for this post

9h 25m 46s logged

WebOS 2 Devlog #11: Reset btn + Notepad IDE + other changes

This was a long long coding session. Had to stay awake till like 2am. Here are the changes i made. Ill try to keep everythign concise because theres a 4000 char limit and i have lot more to say than that.

Change 1:

I added a factory reset button in settings that directs the user to the webos setup screen like the one they get when they first enter the website. When testing this feature, i realised that random variables from completely different web projects started appearing in the File Manager. Because browsers share localStorage databases across the same local port (e.g., 127.0.0.1:5500), the OS was inheriting the ghosts of old projects.

The solution:

I had to upgrade the Initial Setup Utility. When formatting the Virtual Hard Drive, the system now temporarily caches the user’s OS credentials in memory that they entered, executes a total localStorage.clear() wipe to delete all the localStorage varialbles, and then safely restores the username and stuff before continuing normally.

Change 2: Notepad IDE

This was the part that took the longest (and its still not done). I wanted to create something absolutely unique that i havent seen in any other webos projects that i saw. And i realised, why dont i make an IDE in me webos? Not an actual IDE ofc but the goal was to allow users to write raw HTML/JS in the Notepad, save it as a .app file, and double-click it on the desktop to launch it as a fully functioning, program.

Attempt 1 (Failure):

I initially tried parsing the saved text and running it directly in the OS context using eval(). It was an absolute security and stability nightmare. The custom app had root access to the OS memory and instantly overwrote the osState object, completely crashing the Window Manager within seconds.

Attempt 2 (Failure):

I tried fixing attempt 1 but messed up the entire code in the process so i had to revert to that commit and this time, i tried putting the apps in Web Components and the Shadow DOM. While this successfully isolated the CSS so custom apps didn’t break the OS styling, the JavaScript still executed in the global window scope. Running two different custom apps simultaneously caused variable collisions that bricked the taskbar. It was too complex and fundamentally flawed.

I wiped the slate clean again.

Attempt 3 (Success):

I realised that the answer was looking straignt at me. I was so stupid. I can just take the code and slap it on to an , and it runs it, just like how i made the web browser. The solution was that When a user double-clicks a custom .app, the OS takes the raw code and converts it into a text/html Blob. It then passes that Blob through URL.createObjectURL(), creating a localized URL. By feeding that URL into an , the custom app boots perfectly. I am really proud of this feature. It’s still not fully done but i had to make a devlog since the tracked time almost reached 10hrs.

0
0
2
Open comments for this post

4h 27m 9s logged

WebOS 2 Devlog #10: icon implementation + taskbar remodeling

When i looked at the webos, i realised it missed something to look like an actual os. It wasnt realistic enough. So, i decided to do two changes to make it more realistic. Here is what it did:

Change 1:

I added some real user data in the taskbar. More specifically, the host device’s actual network and battery status and date. I used the the browser’s native navigator.onLine and the navigator.getBattery() APIs. I also made it such that the os actively listens for network connection drops such as when wifi is disconnected and battery charging/level events, and updates the data accordingly.

Change 2:

I also noticed that my entire os is filled with emojis for stuff like calculator, file manages (all the apps essentially), the taskbar, the browser, the sites in the browser, etc. THis made it look really unprofessional so i fixed it. I replace all system emojis with Google Material Symbols to make it look a lot better.

I did face one challenge however, the emojis in my website in my web browser weren’t being replaced by icons for some reason and I then realised that the iframe sites acts as a sandbox and they dont inherit the imported apis from the main html file. So I just injected a tag and imported the Google Material Symbols API directly in the isolated HTML code in my js file.

Change 3:

The goal of this change was ot allow the user to snap the taskbar to the top of the screen (Linux style). This was the part that took longer than expected. I originally just added an optoin in the settings to move my taskbar to the top of the screen but the pill-like, floating taskbar i had was really ugly when it was at the top. So, i spent like more than an hour and half trying out new designs and redesigning the taskbar so it looks good both when its at the top and the bottom and finalised a design that actually looks much better than what i had before. It now takes up like the entire bottom/top of the screen instead of floating in the middle liek before. That was all the changes made since the last devlog.

0
0
3
Open comments for this post

3h 16m 11s logged

WebOS 2 Devlog #9: Implemented color accents and some browser improvements

I was originally going to do some debugging and finish of this project but i was looking through other peoples’ webos projects and realised there was much i could improve. I then got like a huge brainwave about new stuff to implement so ig it’ll be a bit longer before I ship this project. One of these ideas was adding color accents because right now my modern theme is limited only to a light pinkish color. Here are the changes i made:

Change 1: Accents

In the settings screen, i added an option to choose the system accents. I also gave some basic presets and added an option to pick a color by adding a color picker option. Implementing this was quite simple, just replace all hardcoded pink colors with –os-accent (which i added in css). I linked htis –os-accents attribute/class to the color that the user chooses in js and made ti that all the places where the accent pops up, the color variable there is replaced with –os-accents. So if the user changes the accent in settings, the places where –os-accent is set changes color automatically.

Challenge 1: Contrasting invisible text
The problem: Swapping a single hex code for an accent color that the user chooses breaks all translucent UI elements (like shadows). Furthermore, if a user picks a bright color (like Mint Green or Yellow), the hardcoded white text on the title bars becomes completely invisible.

The Solution:
I implemented a Hex-to-RGB engine that injects raw RGB values directly into the CSS :root. This solves the first part of the problem. To solve the text contrast issue, I implemented the WCAG Relative Luminance algorithm ( used a bit of outside help here iykwim ;)). The OS now mathematically calculates the perceived brightness of the user’s chosen color. If the relative luminance passes a threshold of 0.179, the OS flips the title bar text to pitch black so its legible comfortable.

Change 2:

i was just playing around in the webbrowser and exploring, and i found some stuff that needed to be fixed: when building a simulated web browser using tags, embedding sites like google resulted in a “Refused to Connect” error. These servers send an X-Frame-Options: DENY header. Because client-side JavaScript is legally blind to server headers, the OS couldn’t detect the block to show the custom error screen I made. I knew this error existed and knew this was a thing but only after experiencing it like a real user did i realise how annoyinf this was and it made my os seem broken.

Solution 1 (attempt):
I initially tried routing requests through a third-party API to read the headers, but ad-blockers and privacy shields just made the API requests not work, crashing the entire browser app (at least thats what i think is the cause).

The Solution:
I used a massive Regex blocklist, such that the browser now instantly intercepts requests to 99% of top-tier websites that block iframes (like youtube or google), and routs the user to a custom error page. (did these stuff with the help of some ai only)

Next Problem:
When a user searches Google inside the iframe and clicks a link in the embedded page, the OS address bar wouldn’t update. This is a browser restriction. Browsers mathematically lock JavaScript out of reading cross-origin URLs for security reasons. At this point i just stopped instead of trying to waste my time trying to break through some military grade (i think?) restrictions.

Change 3:
Before, only iframe compatible websites worked but i had an idea to route all queries (except the ones in websites format) through a google search. Apparently, google.com doesn work in iframe but the google search works. So now if i type hello world, it just redirects me to a google search page with hello world searched.

P.S. I made some other tiny changes aswell but i cant rlly remember them now sry

1
0
1
Open comments for this post

2h 56m 27s logged

WebOS 2 Devlog #8: Migrated to ES6 arch. and split css into any files

I just realised that essentially all my code is squished into three files-index.html, index.css, and index.js. And all of them were quite big. Like the js file had more than 2,000 lines, and css had more than a 1,000 lines. I dont know why i havent noticed it before but im glad that i did now because i was plannign to do a deep debugging session next and it wouldve been hella hard to do in a 2000+ line file. Plus, a single bug in e.g. the calculator could crash the file manager, and debugging required scrolling through thousands of lines of code. So, i decided to migrate the index.js into an ES6 architecture and split the index.css into multiple manageable files.

That’s all i can say for this devlog ig. There was nothing new except some lines of code i had to add after the migration to make sure everything is working. There were no really new features added. But there were many things that delayed me: i accidentally deleted a block of code in the index.css without moving it and didnt notice it so some styles were broken and i had to like retrace my steps and stuff to fix all the problems it caused. That’s all ig. The project is almost coming to an end! Can’t wait to ship it :)

0
0
3
Open comments for this post

3h 55m 37s logged

WebOS 2 Devlog #7: Web Browser Implementation

I reached the final couple of phases of my project and this is one is one of the crucial ones: building a web browser. My plan was to use iframe. But the thing about building a webbrowser inside a webbrowser or inside a sandboxed environment like a website is most websites (about 99%) like google, youtube, or github use X-Frame-Options and Content-Security-Policy: frame-ancestors ‘none’ which means they specifically block their websites from being displayed in cases like this ot prevent clickjacking. So every time i tried loading a webpage, it just says this webpage refused to connect or sth. I used ai to try bypassing it but it didnt work, so with the help of the same aforementioned ai, i implemented a solution.

The solution:

Since I cannot disable host browser security policies, and i dont have a backend proxy server, I had an idea to just build my own native ‘browser’: EpochOS IntraNet (just decided on the name EpochOS btw). This didnt take too long cus i had someone (ai) helping me cus it was almost midnight and i was tired as hell. Here are the features:

  • I wrote a parser that intercepts navigation requests. If the user navigates to webos://home or webos://directory, the engine injects a large data:text/html;charset=utf-8 string directly into the iframe’s src attribute. This opens a local, HTML dashboard without triggering cross-origin blocks. Essentially, i wrote html in js and injected that html into the iframe src, so i essentially made my own ‘web-page’.

  • Standard links inside a data URI iframe will try to navigate the iframe itself, which doesn’t update the OS address bar. To fix this, I set up a window.addEventListener(‘message’) listener on the parent OS. The buttons inside the iframe use parent.postMessage() to pass the target URL up to the OS, allowing the JavaScript engine to handle the routing and update the UI properly.

A real browser alse doesn’t lose a page’s state (like scroll position) when you switch tabs. And im trying to make a real browser. So, to achieve this, the browser engine now doesn’t share a single iframe but rather new ones get created:

  • Every time the user clicks the “New Tab” button, a new node is generated and appended to the container. Switching tabs simply toggles the CSS display property between none and block. This keeps inactive pages fully loaded in memory.

  • Because cross-origin security rules (the ones i mentioned before) lock us out of accessing the iframe’s native window.history object, I had to build a custom history router. Every tab object in the JS array maintains its own history array and a historyIndex pointer. The back/forward buttons just decrement or increment this pointer and re-apply the URL to the iframe. Kinda genius ngl (this was an idea from ai btw)

But for a browser to be useful, it needs to have some proper webpages. After some scouring, i found some webpages that do work in iframe and dont have the restrictions that websites like google do. I’m not gonna tell you what websites those are, you just have to see yourself. I found like 10 or sth so there’ll be plenty of stuff to do.

Other features of the browser include: bookmarking, reloading (i also added a reloading spinner btw) and some more stuff.

0
0
4
Open comments for this post

1h 55m 6s logged

WebOS 2 Devlog #6: UI, UX and functionality improvements

This update focuses heavily on stabilizing what i already have and also refining the less finer aspects of the UI. Here is what i did:

  • Theme improvenets: I overhauled the .theme-retro class. stuff were contradicting each other with one thing saying this and the other saying that (too many to even give an example). I also changed some other minor stuff too like increased the grid size in the desktop to prevent icons from overlapping.

But this was the main change:

  • System Security & Identity Manager: Implemented a global sanitizeIdentity utility (Regex: /[^a-zA-Z0-9_-]/g) to remove spaces and illegal characters from usernames and hostnames when the user sets it before writing to localStorage because if i have sth like ‘John Doe’ as the username and ‘my school computer’ as the host name, the terminal command would look sth like John Doe@my school computer. And this just looks hella ugly.

  • Dedicated Identity UI: removed the raw identity inputs out of the Settings menu like i had before and moved them into a dedicated Identity Manager window because its more secure that way. I also added an authenticaiton wall before this window pops up. To do this, i wrote an async while loop for identity verification. All the users now have successfully pass the password prompt (or use the recover override to bypass the password) before it allows them to modify any identity settings.

  • Bootloader improvements: btn-shutdown now properly halts system processes (clearing systemClockInterval and locking pointer events) instead of just hiding the UI like it did before where it just had like a black screen with text on it saying shutting down and stuff. It now has like a loading screen and all that stuff.

  • Context Booting: i also implemented sessionStorage.setItem(‘boot_context’, ‘warm’) to track system restarts so different boots have like different bootloading sequences (the point below this). This didn’t take too long as i could just copy and past what i had in other sequenes and just take the text.

  • Differnet Boot Sequences: The bootloader now reads the sessionStorage context. A Cold Boot triggers the full POST memory checks and hardware scans (dont know what this is. had to use ai for the sequences cus i didnt know what the data was). A Warm Boot (restart) bypasses POST and executes a different initialization sequence. THis makes the user more immersed in the environment.

0
0
3
Open comments for this post

3h 43m 28s logged

WebOS 2 Devlog #5: File manager overhaul + custom dialog box

I realised that always having the custom browser alerts was kinda boring and interrupting so i made my own dialogue box. I also changed the file manager to include some essential functions that it was missing to make it more like an OS (see below). Here are the changes i made:

  • I abandoned the old array-based folders. I made it so that it now reads and writes directly to localStorage using stricter pathing (e.g., webos-file-Root/Documents/file.txt). I also built a native getUniqueName() function. If you create a duplicate file or folder, there’s no like a (1), (2), etc. at the end of it, which prevents data overwrites. This makes it more like a real OS

  • Drag-and-Drop: I alos removed the old custom JavaScript coordinate trackers for file movement. It now uses the native HTML5 Drag-and-Drop API. You can physically pick up a file from the Explorer window, drag it out, and drop it directly onto the visual Desktop wallpaper.

  • Custom Dialog Box: Native browser popups (alert(), confirm()) look hella ugly and break the flow so i built a custom dialog engine using JavaScript Promises. Now, when the system needs confirmation a custom window that fits with the theme appears. Because it uses async/await, the JavaScript pauses and waits for user acceoting or declining without freezing the browser.

  • List View & Item Properties: I introduced a hybrid Grid/List view (just like a real os like mac). Because tracking file metadata (like Date Modified) from the start would have been way to complicated, I just built this engine where when the File Explorer encounters a file without a timestamp, it instantly generates metadata key (os-meta-path) using Date.now() and saves it permanently, which means that it allows for Date sorting without breaking anything.

0
0
4
Open comments for this post

4h 0m 23s logged

WebOS 2 Devlog #4: Initial bootloading sequence + login (optional)

When i looked at other projects i realised that they all have some kind of flashy bootloading sequences but mine didnt have any so i built one. I didn’t want it to be too flashy so i made a simple, straightforward sequence. I also knew what exactly I wanted so I managed to finish this in 4hrs on the dot or it would’ve taken a lot longer. This is what it consists of:

  • Bootloader that takes into account the selected theme: Since I had two themes in my OS (Modern and Legacy), it didnt make sense for both to have the same loading screen. So the system now actually boots up differnetly before loading the UI. Depending on your settings, you’ll either get a quick Modern UEFI startup, or a 1995 Legacy BIOS sequence complete with memory checks, IDE drive detection, and ASCII loading bars (had to use some outside help [ai] for this one as I’m not that old to know all that stuff).

  • Hardware Interrupts: Just like a real PC, if you hit esc while the system is booting, it triggers a hardware interrupt and drops you into a configuration screen.

  • Interactive OS Installation: If it’s your first time booting up (or you reset your system), you now have to actually “install” the OS. You can type in your preferred Username, network Hostname, and set an Administrator Password right inside the terminal. You even get the option to format your virtual hard drive.

  • Login: If you set a password (which is optoinal) during setup, the boot sequence will actually halt and lock the system until you type it in. (Don’t worry, I added a recover command bypass in case anyone forgets it).

  • Terminal Integration: The CLI terminal now dynamically reads your setup data. Instead of a normal prompt that you used to get with the default user@stardance or sth, you’ll see your actual custom username@hostname:~/$.

  • Loading text: as the os loads and goes through the bootloading sequence some highly advanced random computer text ‘loads’ to add a little bit to the realism. Some of them are actual data from the host computer such as ram, gpu, and stuff like that. I had lots of other text and loading content that came from the the user’s actual real life hardware and software data, which added to the realism I had to research and use ai to make this because I had no knowledge of how computers were back then.

There’s more but it wont fit here so you’ll just have to see it when i host it after my next ship.

0
0
2
Open comments for this post

2h 50m 52s logged

WebOS 2 Devlog #3: Building a UNIX Terminal + some other improvements

This was a major update today for WebOS 2.0 as i built a genuinely realistic CLI. It’s looks and acts like a Mac Terminal (cus i use mac). Here is what i implemented:

  • In the terminal, i implemented the following commands: help, clear, pwd, ls, cd, cat, touch, mkdir, rm, echo, whoami, date, history, and nano. This part itseld wasnt so difficult cus I had previously done something similar before but it was still challenging nonetheless.

  • I wanted the CLI to be as realistic as possible so I implemented (with a little bit of help from gemini) a custom AST-style parser. It fully supports logical command chaining (&&, ||, ;), quotation marks usage (both single and double), and file redirection (>, ») straight into the virtual hard drive.

  • Autocomplete: This was probably the hardest thing i tried to build and i am happy with how it turned out. I implemented a zsh-style Tab completion system. Pressing Tab auto-fills the longest common prefix and then shows all the possible options directly beneath your active prompt. This is one of the things I a most proud of because after using it, it was essentially very similar to the mac Terminal. This autocomplete works both for commands and files/folders.

  • Errors and stuff: The terminal behaves exactly like real bash. If you type ls -la (-la is not implemented [yet?]) or cd too many args, it won’t just blindly execute or fail silently (it originally did so i had to change it), but it will spit back the same error message you’d expect to see on a real machine.

  • GUI/CLI Integration: When i was implementing nano, i tried to think of how to implement a CLI editor. But i then realised, i can just connect the nano command to the notepad that I alreadu made. So typing nano test.txt in the terminal now just launches the Notepad app and opens the file for editing.

And I made some other changes to stuff like the file manager but the terminal implementation above is the biggest change.

0
0
4
Open comments for this post

1h 54m 27s logged

WebOS 2 Devlog #2: UI & UX Debugging + UI Improvements

This was quite a short session mainly focused on debugging. Here are the changes for this session.

  • New Setup Wizard: The Welcome Screen has been completely redesigned into a classic two-pane setup wizard. (In Retro mode, it even has the iconic sideways teal text on the sidebar).

  • State Persistence: The OS now remembers your settings. Your preferences for military time, desktop icon labels, and whether you want to see the welcome screen on boot are all permanently saved to localStorage.

  • Calculator & Layout Fixes: The calculator now properly displays full math expressions (e.g., 3 + 5) instead of instantly wiping the screen. Before it still worked but it just showed the numbers and the answer-it didnt show what the user was doing.

  • I also fixed a ton of bugs. Apps that are maximized now perfectly snap to the taskbar without overlapping, and the File Explorer drag-to-select doesn’t glitch when you move the window because before the drag-to-select used to activate when i was dragging the window.

0
0
2
Open comments for this post

13h 42m 18s logged

WebOS 2 Devlog #1: Transitioning into an actual OS.

The WebOS 2 mission just unlocked so all the time before i spent working on this overhaul, hence the 13 hour devlog.

In the last devlog, i had a very basic beginning: a basic onboarding screen with some text and a “Continue” button. There was no actualy proper desktop, not that many apps, and definitely no File Explorer.

Over the last 13 hours, I managed to change the project into a fully functioning, browser-based operating system with its own virtual file system, and app ecosystem. Here is a breakdown of everything that was built in this time. Since i made a lot of changes, i’ll keep it brief and won’t go into it too much:

  • The Window & Desktop Engine: the core physics of the OS were built completely from scratch.

  • Drag and Drop: Windows can be dragged freely but are strictly clamped to the viewport so they can never be lost off-screen.

  • Window Controls: remade the full Minimize, Maximize, and Close logic.

  • Animations: Implemented a requestAnimationFrame state machine so windows don’t just appear—they like animate and scale and fade out into the taskbar.

  • Desktop Grid: Desktop icons are draggable and auto-snap to an invisible grid when released.

  • File System (File Manager): Going from zero file management to a complete virtual system was perhaps the biggest change. It is powered by localStorage, and the OS now remembers everything:

  • Dynamic File Explorer: Built a grid/list view system complete with a sidebar, path breadcrumbs, and directory navigation.

  • Context Menus: Right-clicking files now opens custom context menus to rename, delete, or restore items.

  • Recycle Bin: Files are moved to a functional Trash directory where they can be permanently emptied or restored to the Root folder.

  • Drag-and-Select: made a custom mouse-drag selection box (the translucent pink lasso) to highlight multiple files at once.

  • App Ecosystem:

  • Themes: I built a dynamic theme engine with two main themes.

  • Modern Dark: The default OS features premium glassmorphism, background blurs, and other stuff, and has like a pink accent color.

  • Retro: It changes the OS back to what it looked like in like 1995 by replacing animations and toggles with grey borders, checkboxes, and the blue desktop background.

  • The New Welcome Screen: That old, basic onboarding screen looked ass so it was completely scrapped. I replaced it with a better and cleaner on that also remembers their preference if they check “Don’t show this on startup.”

0
0
1
Ship #1

I created a simple operating system with HTML, CSS, and Javascript that runs on you web browser. It has a nostalgic look and feel with old-styled buttons and looks. To make it more like an OS, a calculator and a notepad have been created and implemented in the app. Moreover, to allow the user to personalise as much as they want, many settings have been included, from custom wallpapers to wallpapers that come from NASA itself and more.

This was my first large scale project that I have coded so it's an interesting experience for me. Before this, I only used to do challenges on platforms like Codewars and other than some small side projects, I don't have a practical experience. Therefore, i think this project has taught me a lot on how to built stuff yourself.

I hope you like my project :)

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

39m 33s logged

Devlog #3: Onboarding and Eliminating FOUC

Before shipping the WebOS 1 project and moving on to WebOS 2 project, I needed to implement an Onboarding/Welcome Screen to introduce users to the OS environment. This required a full-screen dark overlay.

this is what i did:

  1. Z-index mismatch
    Because my custom Drag Engine automatically increments the zIndex of any .window it touches, the moment I clicked the Welcome Screen, the engine overwrote its god-tier Z-Index (99999). This caused an immediate Z-Index collapse, burying the modal underneath the desktop icons and the dark overlay.
    The Fix: I had to implement a strict exception in the JavaScript mousedown event listener to protect the Welcome Screen’s ID from being overwritten.
    DOM Reordering: To guarantee that the Welcome Screen will be at the very top,, I moved the Welcome Screen to the absolute bottom of the document. This means it will naturally sit on top of the other elements.

  2. Eliminating the FOUC
    I used the localStorage API so users could check a “Don’t show this again” box, saving their preference to the hard drive. However, this caused a massive FOUC bug.
    The Problem: HTML renders faster than JavaScript executes. On boot, the browser would instantly paint the Welcome Screen to the monitor. A few milliseconds later, JavaScript would read the hard drive, realize the user disabled the screen, and violently delete it—causing an ugly flicker.
    Fix: I basically just inverted the rendering logic. I hardcoded ‘display: none;’ directly into the HTML so the modal is completely invisible by default. Now, the browser paints nothing. JavaScript checks the hard drive, and only turns the welcome screen on if it confirms the user actually wants to see it. Now it’s much better.

Ig this is the end of my WebOS 1 project. I will be shipping this project and then moving on to WebOS 2 where I’ll be implementing File Management, In-browser-browser?, and maybe some other built in tools. That’s the plan for now.

0
0
24
Open comments for this post

40m 56s logged

Devlog #2: Debugging + Icon dragging features + localStorage implementation

The core window manager is working properly so this second session was all about polishing the UI and UX aspects. But there were some challenges:

  1. The faulty dragging
    I transitioned the desktop icons from a static flexbox grid to absolute positioning so they could be freely dragged around the screen (like an actual operating system). However, this immediately triggered native browser collisions.

The Problem: When clicking and dragging an icon, the browser saw the action as trying to highlight text or drag an image to a new tab. This triggered a native HTML “ghost drag,” completely overriding my custom JavaScript drag engine and leaving the icon permanently stuck to the cursor.

The Solution: I just basically implemented multiple stuff to solve this:

  1. Applied ‘-webkit-user-select: none’ and ‘user-select: none’ to prevent highlighting.

  2. Injected ‘draggable=“false”’ natively into the HTML.

  3. Applied ‘pointer-events: none’ on the inner emoji and label text. This forces the mouse click to pass through the text and hit the icon container directly, ensuring my custom e.preventDefault() mousedown event works properly every time.

  4. State Persistence (The Local Storage API)
    An OS is useless if it resets every time you turn it on. I wired up the browser’s native localStorage API so it saves some of the stuff that the user did. So far it’s only the position of the icons, but I’m planning to add more stuff to the localStorage. Here are the changes:

Upgraded the mouseup event listener to capture the exact X and Y coordinates of an icon the moment it is let go after dragging.

Built a boot sequence that loops through .desktop-icon elements on page load, fetches their saved coordinates , and implementes them.

  1. Wallpaper changing bug

The NASA API integration was fetching data successfully, but massive high-res images were causing visual lag, leading to a blank blue screen while the image downloaded in the background.

Made a new thing where the newImage() is inserted into the virtual memory of the js.

The UI now triggers a document.body.style.cursor = ‘wait’ loading wheel and displays a “Downloading…” status.

JavaScript intentionally halts the DOM update until the virtual image’s ‘.onload’ event fires, ensuring the wallpaper only gets applied to the screen exactly when it is 100% ready.

Lastly, I also added a setting in the settings tab where the user can choose if the icon labels are hidded or shown.

What’s Next?
The desktop environment is now completely stable, personalized, and persistent. Next up: More UI and UX refinements before shipping for WebOS 1. Gonna implement File Management for WebOS 2 :)

0
0
1
Open comments for this post

4h 59m 46s logged

Devlog #1: Booting Up - Building a Custom Window Manager & Desktop Environment from Scratch

Today marks the official first boot of my WebOS project.

I’m trying to build a full OS that runs in the Web Browser directly using HTML, CSS, and Vanilla JavaScript. It acts like an actual operating system, like windows for example, but the only difference is the way it looks, it’s identity and that it runs in your web browser.

Over the past few hours, I changed the project from a static layout into a fully interactive environment. Here is a breakdown of the core engine and features that I currently built.

  1. The Custom Window Manager
    The hardest part of making an OS is handling window states. I built a universal Drag-and-Drop engine with dynamic Z-Index management.

The Problem: Windows would get stuck behind each other, or the browser would lose track of the mouse if the user dragged too fast or threw the window off-screen, so i wouldn’t be able to drag it back.

The Solution: I implemented an event elegation system attached to the document root, calculating mouse offsets relative to the title bars. This means wherever the mouse moves, the title bars move to keep that offset difference the same, which is essentially what the drag and drop function is. I also engineered physical constraints so windows can never be dragged out of the viewport.

  1. The Desktop Environment
    To not make seem like this is just a website, I completely changed the browser’s default behavior.
    I Implemented double-click event listeners for desktop icons and then overrode the native browser right-click menu (e.preventDefault()) and built a custom OS context menu this makes it feel more unique.

  2. Core Applications
    Notepad: A fully resizable text editor using CSS flexbox so the typing area automatically expands with the window.
    Calculator: Quite self-explanatory. Engineered the math logic from scratch.

Settings (NASA API): Built a customization menu that toggles a global 12hr/24hr clock state, and fetches real-time data from NASA’s APOD API to dynamically change the desktop wallpaper based on the NASA Picture of the Day.

What’s Next?
The UI feels like an OS, but it lacks permanence. Next on the roadmap: File Management. I’ll be engineering a system to actually save the data typed into the Notepad so it survives page refreshes. Also, I want to create a web browser with actual internet access to really bring that OS feeling. That’s all I have planned out.

p.s. I’ve attached some pictures of my website below - hope you like it :)

Stay tuned.

0
0
4

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…