<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: STACKFOLO</title>
    <description>The latest articles on DEV Community by STACKFOLO (@stackfolo).</description>
    <link>https://dev.to/stackfolo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3812321%2Fa3402d43-27b9-4436-8355-76919d8f2785.png</url>
      <title>DEV Community: STACKFOLO</title>
      <link>https://dev.to/stackfolo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stackfolo"/>
    <language>en</language>
    <item>
      <title>How I Track GitHub Commits Across All My Side Projects in One Place</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Mon, 13 Apr 2026 11:08:51 +0000</pubDate>
      <link>https://dev.to/stackfolo/how-i-track-github-commits-across-all-my-side-projects-in-one-place-5a89</link>
      <guid>https://dev.to/stackfolo/how-i-track-github-commits-across-all-my-side-projects-in-one-place-5a89</guid>
      <description>&lt;h1&gt;
  
  
  How I Track GitHub Commits Across All My Side Projects in One Place
&lt;/h1&gt;

&lt;p&gt;At one point last year, I had five active GitHub repositories. Two personal side projects, one open source contribution, a freelance client project, and an experimental thing I started on a weekend. Each had its own commit history, its own pace, and its own "when did I last touch this?" question that I could never answer without opening GitHub.&lt;/p&gt;

&lt;p&gt;I found myself doing this multiple times a day: open GitHub, click into a repo, check the commit log, try to remember if that last commit was yesterday or three days ago. Then repeat for the next repo. It was a small friction, but small frictions compound.&lt;/p&gt;

&lt;p&gt;Here is the system I built to see all my commits in one timeline without leaving my browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Repo-Hopping
&lt;/h2&gt;

&lt;p&gt;GitHub is excellent for individual repositories. The commit log, the PR history, the contribution graph. All great when you are focused on one project.&lt;/p&gt;

&lt;p&gt;But when you are juggling multiple side projects, GitHub's repo-centric design works against you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No cross-repo timeline.&lt;/strong&gt; You cannot see "what did I do across all projects today?" without visiting each repo separately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context switching cost.&lt;/strong&gt; Every repo hop breaks your train of thought. You went to check one commit message and now you are reading an old issue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress blindness.&lt;/strong&gt; Without a unified view, it is easy to think you are making progress everywhere when you are actually only pushing to one repo and neglecting the others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple accounts.&lt;/strong&gt; If you have a personal GitHub and a work GitHub (or a client's org), the fragmentation doubles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Tried First
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub's contribution graph.&lt;/strong&gt; The green squares are motivating but useless for cross-project awareness. They show activity, not what you actually did or where.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub notifications.&lt;/strong&gt; These tell you about other people's activity, not yours. And the signal-to-noise ratio is rough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A text file log.&lt;/strong&gt; I tried keeping a manual log of daily commits. This lasted exactly four days before I forgot to update it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third-party dashboard tools.&lt;/strong&gt; Most of these are designed for teams and managers, not solo developers tracking their own side projects. Overkill for what I needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unified Timeline Approach
&lt;/h2&gt;

&lt;p&gt;What I actually wanted was simple: open one page and see a chronological list of my commits across all repos, mixed in with other project activity. No setup every morning. No manual logging. Just a timeline that updates itself.&lt;/p&gt;

&lt;p&gt;The key insight was that this should live where I already spend time. Not in a separate app I would forget to open, but in my browser, visible every time I open a new tab.&lt;/p&gt;

&lt;p&gt;I set this up using &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-04-w16-reddit-or-bust&amp;amp;utm_content=blog18-cta-inline" rel="noopener noreferrer"&gt;STACKFOLO&lt;/a&gt;, which connects to GitHub via personal access tokens and pulls commit history into a unified timeline. But the concept works with any system that aggregates commit data. Here is why the approach matters more than the specific tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Unified Commit Timeline Shows You
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Where Your Time Actually Goes
&lt;/h3&gt;

&lt;p&gt;When I first set up my cross-repo timeline, I had a surprise. I thought I was splitting time roughly equally between my two main side projects. The timeline showed I had made 23 commits to Project A in the past two weeks and 2 commits to Project B. Project B was not "on pause." It was abandoned, and I had not noticed.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Momentum Gaps
&lt;/h3&gt;

&lt;p&gt;A timeline makes gaps visible. If your last commit to a repo was 9 days ago, you see it immediately. Without a unified view, these gaps hide behind your other activity. You feel productive because you pushed code today, but you pushed to the same repo you always push to.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Context Recovery
&lt;/h3&gt;

&lt;p&gt;When you come back to a project after a break, the first question is "where did I leave off?" A commit timeline answers this in seconds. Your last three commit messages tell you what you were working on, and you can jump back in without re-reading your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Cross-Project Patterns
&lt;/h3&gt;

&lt;p&gt;After a few weeks of data, I noticed patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I only pushed to my open source project on weekends&lt;/li&gt;
&lt;li&gt;My freelance commits clustered on Tuesday and Thursday evenings&lt;/li&gt;
&lt;li&gt;My personal projects got attention in bursts (5 commits in one day, then silence for a week)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was not intentional. Once I saw the pattern, I could decide whether to keep it or change it. I moved my open source contribution to Wednesday mornings, which turned out to be a better fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Multi-Account Tracking
&lt;/h2&gt;

&lt;p&gt;One thing that surprised me: most developers I talk to have more than one GitHub account. Personal, work, sometimes a client org account. Tracking commits across accounts is harder than tracking across repos within one account.&lt;/p&gt;

&lt;p&gt;The approach I use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate a personal access token&lt;/strong&gt; for each GitHub account (read-only scope is enough)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Link each token&lt;/strong&gt; to the projects that use that account&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The timeline merges everything&lt;/strong&gt; chronologically, regardless of which account made the commit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means my personal side project commits, my work repo commits, and my freelance client commits all appear in one stream. I can filter by project when I need to focus, or see everything when I want the big picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond Commits: The Full Project Timeline
&lt;/h2&gt;

&lt;p&gt;Commits are the backbone, but a useful project timeline includes more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task completions.&lt;/strong&gt; When you check off a to-do, it shows in the timeline alongside your commits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource saves.&lt;/strong&gt; When you bookmark a Stack Overflow answer or save a documentation page for a project, it appears in context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service events.&lt;/strong&gt; Subscription renewals, deployment triggers, and domain renewals tied to specific projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual notes.&lt;/strong&gt; Sometimes you need to log "decided to pivot from REST to GraphQL" and have it appear in the timeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns the timeline from a commit log into a project diary. When you look back at a project three months later, you see the full story, not just the code changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Tips for Any Setup
&lt;/h2&gt;

&lt;p&gt;Whether you use a dedicated tool or build your own, here is what I have learned:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cache aggressively.&lt;/strong&gt; GitHub API has rate limits. A 5-minute cache for commit data is enough for personal use and keeps things fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show repo names clearly.&lt;/strong&gt; When commits from 5 repos are interleaved, you need to immediately see which project each commit belongs to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make it visible.&lt;/strong&gt; The timeline only works if you see it regularly. A browser new tab page, a pinned tab, or a widget on your desktop. Somewhere you cannot avoid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter by project when you are focused.&lt;/strong&gt; The unified view is for awareness. When you sit down to code on Project A, filter to just that project so you can pick up where you left off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not over-engineer it.&lt;/strong&gt; The point is awareness, not analytics. You do not need charts and graphs. A simple chronological list with dates, repo names, and commit messages is enough.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;After three months with a unified commit timeline, I shipped two side projects that had been stalled for months. Not because the timeline gave me more time, but because it made my neglect visible. When you see "last commit: 12 days ago" every time you open a browser tab, it is hard to pretend you are still working on something.&lt;/p&gt;

&lt;p&gt;The developers who finish side projects are not the ones with perfect plans. They are the ones who can see where all their projects stand at a glance.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want a unified GitHub timeline in your browser's new tab? &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-04-w16-reddit-or-bust&amp;amp;utm_content=blog18-cta-bottom" rel="noopener noreferrer"&gt;Try STACKFOLO on the Chrome Web Store&lt;/a&gt;. It is free to start, and GitHub integration works with public repos on the free tier.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>sideprojects</category>
      <category>productivity</category>
      <category>developertools</category>
    </item>
    <item>
      <title>How a Daily Dev Log Helped Me Actually Ship My Side Projects</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Mon, 13 Apr 2026 11:05:18 +0000</pubDate>
      <link>https://dev.to/stackfolo/how-a-daily-dev-log-helped-me-actually-ship-my-side-projects-41j9</link>
      <guid>https://dev.to/stackfolo/how-a-daily-dev-log-helped-me-actually-ship-my-side-projects-41j9</guid>
      <description>&lt;h1&gt;
  
  
  How a Daily Dev Log Helped Me Actually Ship My Side Projects
&lt;/h1&gt;

&lt;p&gt;I used to start side projects with excitement and abandon them within three weeks. Not because I lost interest, but because I lost track. I could not remember what I did yesterday, what I should do next, or whether I was making real progress or just staying busy.&lt;/p&gt;

&lt;p&gt;The fix was embarrassingly simple: I started keeping a daily dev log. Not a fancy journaling app, not a 500-word diary entry, just a 2-minute check-in at the end of each coding session. Six months later, I have shipped two side projects and maintained a third. Here is the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Side Projects Die in Silence
&lt;/h2&gt;

&lt;p&gt;Most side projects do not fail because of bad ideas or missing skills. They fail because there is no feedback loop.&lt;/p&gt;

&lt;p&gt;At your day job, you have standups, sprint reviews, PRs that get comments. Someone notices when you ship something. Someone notices when you are stuck.&lt;/p&gt;

&lt;p&gt;Solo side projects have none of that. You code for an hour, close your laptop, and the next time you open it you have lost all context. Multiply that by a few days and the project feels like a stranger's codebase.&lt;/p&gt;

&lt;p&gt;The daily dev log replaces the feedback loop that a team normally provides. It is your personal standup, retro, and progress report rolled into one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2-Minute Dev Log Format
&lt;/h2&gt;

&lt;p&gt;My daily log takes less than 2 minutes and captures four things:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Focus Time (How Long Did I Actually Code?)
&lt;/h3&gt;

&lt;p&gt;Not "time at desk" but actual focused coding time. I track this in hours, and I am honest about it. If I spent 90 minutes with my editor open but only 40 minutes writing code, I log 40 minutes.&lt;/p&gt;

&lt;p&gt;This number alone changed my perspective. I thought I was "coding every day" but my log showed I averaged 25 minutes on weekdays and 45 minutes on weekends. Knowing the real number helped me set realistic expectations.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Mood Check (How Did the Session Feel?)
&lt;/h3&gt;

&lt;p&gt;I pick one of five options: great, good, okay, rough, or terrible. Simple as that.&lt;/p&gt;

&lt;p&gt;This sounds unnecessary until you spot patterns. I noticed that my "rough" sessions clustered on Mondays and Wednesdays. Turns out those were the days I had late meetings at work, and I was trying to code while mentally exhausted. Moving my side project time to mornings on those days fixed the pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Wasted Time (What Stole My Focus?)
&lt;/h3&gt;

&lt;p&gt;I log any time I spent on non-productive activities during my intended coding window. Scrolling Twitter, reading unrelated articles, rabbit-holing into configuration that did not matter.&lt;/p&gt;

&lt;p&gt;The point is not guilt. The point is data. When I saw "30min researching the perfect ESLint config" three days in a row, I realized I was procrastinating on the actual hard problem (auth flow implementation).&lt;/p&gt;

&lt;h3&gt;
  
  
  4. One-Line Summary (What Did I Actually Do?)
&lt;/h3&gt;

&lt;p&gt;One sentence. Not a paragraph, not a bullet list, one sentence.&lt;/p&gt;

&lt;p&gt;Examples from my actual log:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Added user signup form and validation"&lt;/li&gt;
&lt;li&gt;"Debugged OAuth callback, still broken"&lt;/li&gt;
&lt;li&gt;"Refactored database schema, no visible progress"&lt;/li&gt;
&lt;li&gt;"Stared at the Stripe docs for 40 minutes"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the most valuable part. When you open your project after a 3-day break, reading the last few one-liners brings you back to context in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changes After 30 Days
&lt;/h2&gt;

&lt;p&gt;The daily log does not feel useful on day 1. It starts paying off around day 14, and by day 30 it becomes something you actually want to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 1-2: Awareness.&lt;/strong&gt; You realize how little focused time you actually spend on side projects. This is uncomfortable but necessary. You cannot optimize what you do not measure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 3-4: Pattern recognition.&lt;/strong&gt; You spot the days, times, and conditions where you do your best work. You also spot your procrastination triggers. Mine is "research" that never leads to a commit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 2+: Momentum proof.&lt;/strong&gt; When motivation dips (and it will), you scroll back through your log and see 30+ days of entries. The continuity itself becomes motivating. You have evidence that you are a person who works on side projects consistently, even if some days are only 20 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Weekly Review: Where Shipping Happens
&lt;/h2&gt;

&lt;p&gt;Once a week, I spend 10 minutes reviewing my daily logs. I ask three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What did I ship this week?&lt;/strong&gt; Not "work on" but actually ship. A deployed feature, a merged PR, a published page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What blocked me?&lt;/strong&gt; If the same blocker appears multiple days, it needs a different approach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What should I focus on next week?&lt;/strong&gt; Based on what I learned, not what I planned months ago.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This weekly review is where vague progress turns into concrete shipping. Without it, the daily log is just a diary. With it, the daily log becomes a project management system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Satisfaction Rating: The Metric That Matters
&lt;/h2&gt;

&lt;p&gt;I added one more thing to my log after the first month: a satisfaction rating from 1 to 5. Not "how productive was I" but "how satisfied am I with today's session."&lt;/p&gt;

&lt;p&gt;This distinction matters. A 20-minute session where you fix one critical bug can feel more satisfying than a 2-hour session of boilerplate setup. The satisfaction rating helps you optimize for meaningful work, not just clock hours.&lt;/p&gt;

&lt;p&gt;Over time, I noticed that my most satisfying sessions shared common traits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I started with a clear, single objective&lt;/li&gt;
&lt;li&gt;I avoided context switching mid-session&lt;/li&gt;
&lt;li&gt;I committed and pushed before closing my laptop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sessions with low satisfaction usually involved starting without knowing what to do, or trying to make progress on three things at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools for Daily Dev Logging
&lt;/h2&gt;

&lt;p&gt;You can start with anything. A text file, a spreadsheet, or even a physical notebook. The format matters less than the consistency.&lt;/p&gt;

&lt;p&gt;I tried several approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain text file&lt;/strong&gt;: Works but easy to forget. No structure enforcement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spreadsheet&lt;/strong&gt;: Good for tracking numbers but clunky on mobile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notion/Obsidian&lt;/strong&gt;: Powerful but too much friction for a 2-minute entry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventually I built the daily log directly into &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-04-w16-reddit-or-bust&amp;amp;utm_content=blog16-cta-inline" rel="noopener noreferrer"&gt;STACKFOLO&lt;/a&gt;, my project dashboard Chrome extension. It captures focus time, mood, wasted time, satisfaction, and a one-liner, and it generates an AI summary at the end of each day. The new tab page means I see my log every time I open a browser tab, which keeps the habit visible.&lt;/p&gt;

&lt;p&gt;But honestly, a spreadsheet works too. The system is what matters, not the tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;If you want to try this, here is the minimum viable daily dev log:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick a time.&lt;/strong&gt; Right after your coding session ends, not the next morning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log four things.&lt;/strong&gt; Focus time (minutes), mood (1-5), wasted time (minutes), one-line summary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not skip days.&lt;/strong&gt; Even if you did zero coding, log "0 min, did not code today." The streak of entries matters more than the content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review weekly.&lt;/strong&gt; Every Sunday, read your last 7 entries. Ask: what did I ship? What blocked me? What is next?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start tomorrow. It takes 2 minutes. In a month, you will have 30 data points about your coding habits that no productivity article can give you.&lt;/p&gt;

&lt;p&gt;The developers who ship side projects are not the ones with the most free time. They are the ones who know exactly where their time goes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you want a daily log built into your browser's new tab, &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-04-w16-reddit-or-bust&amp;amp;utm_content=blog16-cta-bottom" rel="noopener noreferrer"&gt;try STACKFOLO on the Chrome Web Store&lt;/a&gt;. It is free to start.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>developerlife</category>
      <category>logging</category>
    </item>
    <item>
      <title>How I Use a Weekly Timetable to Balance My Dev Job and Side Projects</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Mon, 06 Apr 2026 09:04:11 +0000</pubDate>
      <link>https://dev.to/stackfolo/how-i-use-a-weekly-timetable-to-balance-my-dev-job-and-side-projects-43j3</link>
      <guid>https://dev.to/stackfolo/how-i-use-a-weekly-timetable-to-balance-my-dev-job-and-side-projects-43j3</guid>
      <description>&lt;h1&gt;
  
  
  How I Use a Weekly Timetable to Balance My Dev Job and Side Projects
&lt;/h1&gt;

&lt;p&gt;Last year I had a problem that I think most developers share: I wanted to work on side projects, but after 8 hours of coding at my day job, I never had the energy or structure to make it happen.&lt;/p&gt;

&lt;p&gt;I tried blocking "side project time" on my calendar. That lasted about a week. I tried waking up early. That lasted three days. I tried the "just do 30 minutes a day" advice, but without knowing which 30 minutes or what to work on, those sessions rarely materialized.&lt;/p&gt;

&lt;p&gt;What finally worked was building a visible weekly timetable. Not a to-do list, not a vague calendar block, but a 7-day grid that mapped specific routines to specific time slots. Here is the system, and why it works when other approaches did not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with "Find Time for Side Projects"
&lt;/h2&gt;

&lt;p&gt;The advice you usually hear is some version of "schedule it" or "make it a priority." This is technically correct and practically useless.&lt;/p&gt;

&lt;p&gt;Here is what actually happens when a developer tries to fit side projects into their week:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Monday evening&lt;/strong&gt;: "I'll code after dinner." You eat, check your phone, and suddenly it is 10pm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tuesday evening&lt;/strong&gt;: "Tonight for real." You open your laptop, stare at the code for 5 minutes, cannot remember where you left off, close the laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wednesday&lt;/strong&gt;: You skip entirely. No guilt yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thursday&lt;/strong&gt;: You feel guilty. You open the project. Spend 20 minutes just getting back into context. Write 10 lines of code. Feel unsatisfied.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Friday&lt;/strong&gt;: "I'll catch up this weekend."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekend&lt;/strong&gt;: You do a burst of 4 hours on Saturday, feel productive, then do nothing Sunday.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sound familiar? The pattern repeats because there is no structure holding it together. You are relying on motivation and willpower, which are both exhausted after a full day of knowledge work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Visual Timetable Works
&lt;/h2&gt;

&lt;p&gt;A timetable is different from a calendar or a to-do list in one important way: it maps routines to time slots across the entire week at a glance.&lt;/p&gt;

&lt;p&gt;When you look at a 7-day-by-24-hour grid, you can immediately see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where your committed time is (work, sleep, commute)&lt;/li&gt;
&lt;li&gt;Where your available blocks actually are&lt;/li&gt;
&lt;li&gt;Whether your side project time is realistic or wishful thinking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This visibility is the key. Most developers overestimate their available time because they think in terms of "evenings and weekends" without subtracting meals, exercise, family time, and the recovery period after focused work.&lt;/p&gt;

&lt;p&gt;A timetable forces honesty. When you see that Tuesday evening has exactly one 90-minute block between dinner and sleep, you stop pretending you will "code for 3 hours" and start planning for what you can realistically do in 90 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Weekly Timetable System
&lt;/h2&gt;

&lt;p&gt;Here is the system I have been using for 6 months:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Map Your Fixed Commitments
&lt;/h3&gt;

&lt;p&gt;Fill in the non-negotiables first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work hours (e.g., 9am-6pm weekdays)&lt;/li&gt;
&lt;li&gt;Sleep (e.g., 11pm-7am)&lt;/li&gt;
&lt;li&gt;Meals, commute, exercise&lt;/li&gt;
&lt;li&gt;Family or social commitments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This usually eliminates 70-80% of your week immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Identify Your Real Available Blocks
&lt;/h3&gt;

&lt;p&gt;Look at what is left. For most employed developers, it comes down to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weekday mornings&lt;/strong&gt; (30-60 min before work, if you are a morning person)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekday evenings&lt;/strong&gt; (1-2 hours after dinner, energy permitting)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekend blocks&lt;/strong&gt; (2-4 hour chunks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be honest about energy levels. A 7pm Tuesday slot after a day of debugging production issues is not the same as a 9am Saturday slot with fresh coffee.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Assign Routines, Not Tasks
&lt;/h3&gt;

&lt;p&gt;This is the critical difference. Do not put "fix authentication bug" in your Tuesday 7pm slot. Instead, assign a routine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tuesday 7pm-8:30pm&lt;/strong&gt;: Side project coding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thursday 7pm-8pm&lt;/strong&gt;: Code review + planning for weekend session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saturday 9am-12pm&lt;/strong&gt;: Deep work on main side project&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sunday 10am-11am&lt;/strong&gt;: Weekly review + milestone check&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Routines repeat every week. Tasks change. When you assign a routine to a slot, you remove the daily decision of "should I work on my side project tonight?" The answer is already decided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Start with 3-4 Slots Per Week
&lt;/h3&gt;

&lt;p&gt;The biggest mistake is scheduling side project time every single evening. You will burn out in two weeks.&lt;/p&gt;

&lt;p&gt;Start with 3-4 slots per week. That is 4-8 hours of focused side project time. More than enough to make real progress if the sessions are structured.&lt;/p&gt;

&lt;p&gt;Here is what a realistic developer timetable looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         Mon    Tue    Wed    Thu    Fri    Sat       Sun
7:00am   --     --     Jog    --     --     --        --
9:00am   Work   Work   Work   Work   Work   PROJECT   --
12:00pm  Work   Work   Work   Work   Work   Lunch     --
2:00pm   Work   Work   Work   Work   Work   Free      --
6:00pm   Dinner Dinner Dinner Dinner Dinner Dinner    --
7:00pm   Free   CODE   Free   Plan   Free   Free      --
8:30pm   --     --     --     --     --     --        Review
10:00pm  Read   Read   Read   Read   Read   Read      Read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Four side-project slots: Tuesday evening coding, Thursday evening planning, Saturday morning deep work, Sunday evening review. That is roughly 7 hours per week, enough to ship meaningful features on a monthly cadence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Make the Timetable Visible
&lt;/h3&gt;

&lt;p&gt;A timetable that lives in a spreadsheet you never open is useless. The whole point is that you see your weekly rhythm at a glance.&lt;/p&gt;

&lt;p&gt;I keep mine in a place I see every day. Every time I open a new browser tab, there is my timetable. The visual cue is the difference between "oh right, it is Tuesday, that is my coding evening" and "I wonder what I should do tonight."&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed After 6 Months
&lt;/h2&gt;

&lt;p&gt;Before the timetable, I shipped maybe one side project feature per quarter. Random, inconsistent progress.&lt;/p&gt;

&lt;p&gt;After 6 months of the weekly timetable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shipped 3 features&lt;/strong&gt; on my main side project&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced guilt&lt;/strong&gt; about not working on side projects (if it is not a scheduled slot, I am allowed to rest)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better work-life separation&lt;/strong&gt; (side project time is defined, not infinite)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekend sessions became 2-3x more productive&lt;/strong&gt; because Thursday evening planning meant I always knew what to work on Saturday morning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The counter-intuitive part: having less scheduled time made me more productive. Constraints force focus. When you know you only have 90 minutes on Tuesday evening, you do not waste 20 minutes deciding what to work on. You open your plan from Thursday and start coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pitfalls to Avoid
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do not fill every evening.&lt;/strong&gt; Recovery time is not wasted time. If you code all day at work and then code every evening, you will burn out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not skip the planning slot.&lt;/strong&gt; The Thursday evening (or whenever you schedule it) planning session is not optional. Without it, your coding sessions become aimless and you lose the momentum advantage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not treat weekends as unlimited.&lt;/strong&gt; Schedule a specific block (like Saturday 9am-12pm) and stop when it ends. "I'll just code all weekend" leads to skipping entire weekends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not beat yourself up for missing a slot.&lt;/strong&gt; You will miss sessions. Illness, social events, bad days. The timetable survives because it repeats every week. One missed Tuesday does not break the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started This Week
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Draw a 7-day grid (paper, spreadsheet, or a timetable tool)&lt;/li&gt;
&lt;li&gt;Fill in your fixed commitments first&lt;/li&gt;
&lt;li&gt;Pick 3-4 realistic slots for side project work&lt;/li&gt;
&lt;li&gt;Assign one slot specifically for planning/review&lt;/li&gt;
&lt;li&gt;Put the timetable somewhere you see it daily&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I built this system into &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-04-w15-outreach&amp;amp;utm_content=devto-cta-bottom" rel="noopener noreferrer"&gt;STACKFOLO&lt;/a&gt;, which has a 7-day timetable grid where you drag routines into time slots and see your week at a glance on every new tab. But the approach works with any tool that lets you visualize a weekly schedule. The key is not the tool. It is the visibility.&lt;/p&gt;

&lt;p&gt;Stop trying to "find time" for side projects. Build a timetable that shows you where the time already is.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>routines</category>
      <category>timemanagement</category>
    </item>
    <item>
      <title>I Had 400+ Bookmarks and Zero Organization. Here's What Fixed It.</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Mon, 30 Mar 2026 09:15:08 +0000</pubDate>
      <link>https://dev.to/stackfolo/i-had-400-bookmarks-and-zero-organization-heres-what-fixed-it-4h5h</link>
      <guid>https://dev.to/stackfolo/i-had-400-bookmarks-and-zero-organization-heres-what-fixed-it-4h5h</guid>
      <description>&lt;h1&gt;
  
  
  I Had 400+ Bookmarks and Zero Organization. Here's What Fixed It.
&lt;/h1&gt;

&lt;p&gt;Last month I counted my Chrome bookmarks. 437 items spread across 12 folders with names like "Useful," "Check Later," and my personal favorite, "Misc 2."&lt;/p&gt;

&lt;p&gt;I could not find anything when I actually needed it. That React hooks tutorial I bookmarked three weeks ago? Buried somewhere between a CSS grid cheatsheet and a random Medium article about Kubernetes. The Stack Overflow answer that solved my auth bug? No idea which folder it ended up in.&lt;/p&gt;

&lt;p&gt;Sound familiar? If you are a developer who saves web resources "for later," you probably have the same problem. The bookmark bar was never designed for knowledge management. It was designed for quick links to Gmail.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem: Saving Is Easy, Organizing Is Not
&lt;/h2&gt;

&lt;p&gt;Here is what typically happens. You find a useful article, tutorial, or documentation page. You hit Ctrl+D or click the star icon. Chrome asks you to pick a folder. You pick the closest match or just leave it in "Other Bookmarks."&lt;/p&gt;

&lt;p&gt;Two weeks later, you need that resource. You open your bookmarks, scroll through 50 items in the wrong folder, give up, and Google the same thing again.&lt;/p&gt;

&lt;p&gt;The friction is not in saving. It is in organizing at the moment of saving. When you are deep in a coding session and you find a useful resource, the last thing you want to do is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Think about which category it belongs to&lt;/li&gt;
&lt;li&gt;Add relevant tags&lt;/li&gt;
&lt;li&gt;Write a note about why you saved it&lt;/li&gt;
&lt;li&gt;Connect it to the right project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So you skip all of that, hit save, and move on. The bookmark becomes a digital post-it note you will never find again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Tried Before
&lt;/h2&gt;

&lt;p&gt;I went through the usual progression:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser folders&lt;/strong&gt;: Created a careful hierarchy. Frontend &amp;gt; React &amp;gt; Hooks &amp;gt; Custom Hooks. Maintained it for about two weeks before defaulting back to dumping everything in "Misc."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notion database&lt;/strong&gt;: Set up a resource database with tags, categories, and a nice gallery view. The overhead of switching to Notion, pasting the URL, filling in fields, and switching back killed my workflow every single time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Raindrop.io&lt;/strong&gt;: Better than raw bookmarks. Decent tagging. But I still had to manually categorize everything, and I stopped doing it after the first month.&lt;/p&gt;

&lt;p&gt;The pattern was always the same. Any system that requires manual organization at save time eventually gets abandoned. You need zero-friction saving with automatic organization.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Shift: Let AI Do the Categorizing
&lt;/h2&gt;

&lt;p&gt;The approach that finally worked was simple: remove the human from the organization step entirely.&lt;/p&gt;

&lt;p&gt;Instead of deciding categories and tags myself, I started using a system where AI analyzes the page content at save time and generates the metadata automatically. You press a shortcut (Alt+Shift+S in my case), the page gets analyzed, and it comes back with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A category (tutorial, reference, library, research, design, etc.)&lt;/li&gt;
&lt;li&gt;Relevant tags based on the actual content&lt;/li&gt;
&lt;li&gt;A one-line description summarizing why the page is useful&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference is dramatic. Here is a real example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before (manual save)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Title: "useEffect cleanup explained"&lt;/li&gt;
&lt;li&gt;Folder: React (if I remembered)&lt;/li&gt;
&lt;li&gt;Tags: none&lt;/li&gt;
&lt;li&gt;Notes: none&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After (AI-analyzed save)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Title: "A Complete Guide to useEffect Cleanup Functions"&lt;/li&gt;
&lt;li&gt;Category: Tutorial&lt;/li&gt;
&lt;li&gt;Tags: react, hooks, useEffect, cleanup, memory-leaks&lt;/li&gt;
&lt;li&gt;Description: "Explains when and how to use cleanup functions in useEffect to prevent memory leaks and stale state in React components"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same resource, completely different findability. Three months later, searching for "memory leaks react" actually surfaces this bookmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a System Around It
&lt;/h2&gt;

&lt;p&gt;AI categorization solved the save-time friction, but I needed a few more pieces to make it a real knowledge base:&lt;/p&gt;

&lt;h3&gt;
  
  
  Project-based filtering
&lt;/h3&gt;

&lt;p&gt;Most of my saved resources relate to a specific project. That React hooks article matters for my SaaS frontend, not my CLI tool. Connecting resources to projects means I can pull up "everything I saved for Project X" in one click instead of searching through a flat list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Star ratings for quality
&lt;/h3&gt;

&lt;p&gt;Not all resources are equal. A comprehensive official docs page is more valuable than a quick blog post. I started rating resources on a 1-5 scale after actually using them. This turned my bookmark pile into a curated library where the best resources float to the top.&lt;/p&gt;

&lt;h3&gt;
  
  
  Active vs. archived
&lt;/h3&gt;

&lt;p&gt;Resources have a shelf life. That webpack config tutorial from 2023 is probably outdated. Instead of deleting it (what if I need it?), marking it as archived keeps the active list clean while preserving the reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers After 3 Months
&lt;/h2&gt;

&lt;p&gt;Here is where I landed after using this approach consistently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;437 bookmarks&lt;/strong&gt; migrated and organized (took about a week of gradual AI re-categorization)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 clean categories&lt;/strong&gt; instead of 12 messy folders&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average 3.2 tags per resource&lt;/strong&gt; (vs. zero before)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to find a saved resource&lt;/strong&gt;: ~5 seconds (search by tag or category) vs. ~2 minutes of scrolling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest win is not the organization itself. It is that I actually use my saved resources now. Before, bookmarking was just a way to feel productive without being productive. Now it is an actual reference system.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Tell Past Me
&lt;/h2&gt;

&lt;p&gt;If you are sitting on hundreds of unorganized bookmarks right now, here is what I wish I had known:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stop organizing manually.&lt;/strong&gt; Any system that depends on your willpower to categorize things at save time will fail. Automate the categorization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Connect resources to projects.&lt;/strong&gt; A flat list of bookmarks is useless. Context matters. "I saved this for the auth system rewrite" is 10x more useful than "I saved this somewhere."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Do not migrate all at once.&lt;/strong&gt; Re-organize gradually. Save new resources properly, and re-categorize old ones when you actually encounter them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rate after using, not after saving.&lt;/strong&gt; You do not know if a resource is good until you actually reference it during work. Come back and rate it later.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the system I built into &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-03-w14-content&amp;amp;utm_content=devto-cta-inline" rel="noopener noreferrer"&gt;STACKFOLO&lt;/a&gt;, where the AI Smart Save feature handles the categorization automatically and connects everything to your project dashboard. But honestly, even a well-structured Notion database with consistent tagging habits would be a massive upgrade over raw bookmarks.&lt;/p&gt;

&lt;p&gt;The point is not the tool. The point is removing yourself from the organization bottleneck. Let automation handle the boring part so you can focus on actually building things.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What is your bookmark situation like? Have you found a system that works, or are you still in the "Misc 2" folder stage? I would love to hear what approaches have worked for other developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>bookmarks</category>
      <category>productivity</category>
      <category>ai</category>
      <category>developertools</category>
    </item>
    <item>
      <title>How I Built a Daily Coding Habit (And Stopped Abandoning Side Projects)</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Mon, 23 Mar 2026 03:08:10 +0000</pubDate>
      <link>https://dev.to/stackfolo/how-i-built-a-daily-coding-habit-and-stopped-abandoning-side-projects-b67</link>
      <guid>https://dev.to/stackfolo/how-i-built-a-daily-coding-habit-and-stopped-abandoning-side-projects-b67</guid>
      <description>&lt;h1&gt;
  
  
  How I Built a Daily Coding Habit (And Stopped Abandoning Side Projects)
&lt;/h1&gt;

&lt;p&gt;I have started and abandoned more side projects than I can count. The pattern was always the same: a burst of motivation on a weekend, three intense coding sessions, then nothing for two weeks. By the time I came back, I had lost all context. The codebase felt unfamiliar. The enthusiasm was gone. Another repo joined the graveyard.&lt;/p&gt;

&lt;p&gt;The problem was never ideas or technical skill. It was consistency. I could write code for eight hours when I was excited, but I could not write code for thirty minutes when I was not. And "not excited" describes most weekday evenings after a full day of work.&lt;/p&gt;

&lt;p&gt;What changed was not willpower. It was systems. Specifically, separating what I need to do (tasks) from what I need to repeat (routines), and scheduling routines like immovable blocks in my week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Task vs. Routine Distinction
&lt;/h2&gt;

&lt;p&gt;Most to-do apps treat everything as a task. "Implement auth flow" sits next to "practice algorithms" in the same list. But these are fundamentally different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tasks&lt;/strong&gt; are one-time items with a completion state. You implement auth, you check it off, it is done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routines&lt;/strong&gt; are recurring behaviors you want to sustain. Algorithm practice is not "done." You want to do it every weekday morning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mixing them in one list creates a problem: routines compete with tasks for your attention, and tasks always win because they feel more urgent. "Fix the deployment bug" will always beat "practice dynamic programming" when they sit in the same list.&lt;/p&gt;

&lt;p&gt;The fix: separate them completely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Routine Grid
&lt;/h2&gt;

&lt;p&gt;I started with a simple weekly grid. Days across the top, time slots down the side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         Mon    Tue    Wed    Thu    Fri    Sat    Sun
Morning  Algo   Algo   Algo   Algo   Algo   ---    ---
Lunch    Blog   ---    Blog   ---    Blog   ---    ---
Evening  Side   Side   Side   Side   ---    Side   Side
         Proj   Proj   Proj   Proj          Proj   Proj
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rules were simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Each block is 30 minutes minimum.&lt;/strong&gt; Not two hours. Not "until I feel like stopping." Thirty minutes, then done. Most days I do more, but the commitment is only thirty minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Morning routines before checking email.&lt;/strong&gt; Algorithm practice happens first because once I open Slack, the day takes over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evening routines have a fixed start time.&lt;/strong&gt; "After dinner" is too vague. "8:00 PM" is specific. I set an alarm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekends are optional but structured.&lt;/strong&gt; Saturday and Sunday have side project blocks but no algorithm practice. Rest days for specific routines prevent burnout.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The ONE Thing Filter
&lt;/h2&gt;

&lt;p&gt;The hardest part is not scheduling routines. It is choosing which routines earn a slot. There are dozens of things I "should" be doing: LeetCode, system design study, open source contributions, blog writing, learning Rust, reading technical books.&lt;/p&gt;

&lt;p&gt;I borrowed a filter from Gary Keller's "The ONE Thing": what is the single most important thing I can do right now that makes everything else easier or unnecessary?&lt;/p&gt;

&lt;p&gt;For my goal of launching a SaaS product, the answer was clear: ship code daily. Algorithm practice supports long-term career growth. Blog writing builds an audience. But shipping code is the ONE Thing that moves the product forward.&lt;/p&gt;

&lt;p&gt;So "Side Project" gets the most slots (5 evenings + 2 weekend days). Algorithm practice gets weekday mornings only. Blogging gets three lunch slots. Everything else either fits into existing slots or waits.&lt;/p&gt;

&lt;p&gt;This filter prevents the common mistake of scheduling twelve routines and sustaining zero. Three to four core routines is the realistic maximum for most people with full-time jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Track (And What I Don't)
&lt;/h2&gt;

&lt;p&gt;I track two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Streaks.&lt;/strong&gt; How many consecutive days I completed each routine. Not to guilt myself when the streak breaks, but to notice patterns. If my evening coding streak breaks every Thursday, that tells me Thursdays are bad for evening work. I adjust the schedule instead of forcing it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Weekly completion rate.&lt;/strong&gt; Out of my 15 scheduled routine blocks per week, how many did I actually do? My target is 80%, not 100%. Hitting 100% every week is unsustainable. Hitting 80% means I missed three blocks, which is normal life.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What I do not track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hours spent. Time in seat is not the same as progress.&lt;/li&gt;
&lt;li&gt;Lines of code. Meaningless metric.&lt;/li&gt;
&lt;li&gt;"Productivity scores." Gamification makes me optimize for the score, not the work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Results After Three Months
&lt;/h2&gt;

&lt;p&gt;Before the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Side project commits: 2-3 per week, clustered on weekends&lt;/li&gt;
&lt;li&gt;Algorithm practice: "when I feel like it" (roughly twice a month)&lt;/li&gt;
&lt;li&gt;Blog posts: 0 per month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After three months:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Side project commits: 8-12 per week, spread across all weekdays&lt;/li&gt;
&lt;li&gt;Algorithm practice: 5 days per week, 20+ minutes each&lt;/li&gt;
&lt;li&gt;Blog posts: 2-3 per month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The total hours spent did not increase dramatically. What changed was distribution. Instead of eight hours on Saturday and zero on Wednesday, I spent one hour on five different days. The context retention alone made each session more productive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Tips for Starting
&lt;/h2&gt;

&lt;p&gt;If you want to try this system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with two routines, not five.&lt;/strong&gt; Pick the two that matter most to your current goal. Add more only after two weeks of consistency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make the blocks small.&lt;/strong&gt; Thirty minutes is better than two hours because you will actually do thirty minutes on a tired Tuesday evening. You will not do two hours.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Schedule around energy, not free time.&lt;/strong&gt; If you are mentally sharp in the morning, put the hardest routine there. Side project coding after a full workday needs the easiest possible entry point (fix a small bug, write one test).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Track visually.&lt;/strong&gt; A weekly grid where you can see filled vs. empty blocks at a glance is more motivating than a list of checkboxes. Something about seeing the pattern makes you want to keep it going.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Review weekly, not daily.&lt;/strong&gt; Daily reviews create anxiety. Weekly reviews let you see the bigger pattern and adjust without overreacting to one bad day.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tools for This System
&lt;/h2&gt;

&lt;p&gt;You can do this with a spreadsheet. Seriously. A Google Sheet with days as columns and time slots as rows works fine for the first month.&lt;/p&gt;

&lt;p&gt;If you want something more structured, I built this system into &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-03-w13-growth&amp;amp;utm_content=devto-coding-habit-cta" rel="noopener noreferrer"&gt;STACKFOLO&lt;/a&gt;, a Chrome new-tab dashboard. Its Routine Blocks feature lets you drag habits into a visual weekly grid with Morning/Afternoon/Evening/Anytime slots, track streaks, and separate routines from one-time tasks. There are 50+ habit templates for developers (algorithm practice, code reviews, blog writing, etc.) so you do not start from scratch.&lt;/p&gt;

&lt;p&gt;But the tool matters less than the system. Separate tasks from routines. Schedule routines as blocks. Use the ONE Thing filter to choose which routines earn a slot. Track streaks and weekly completion. Review and adjust weekly.&lt;/p&gt;

&lt;p&gt;The goal is not to fill every hour. It is to show up consistently enough that your side project stops feeling like a stranger's codebase every time you open it.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>habits</category>
      <category>sideprojects</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building a Chrome Extension with Manifest V3: Lessons from STACKFOLO</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Mon, 16 Mar 2026 13:42:09 +0000</pubDate>
      <link>https://dev.to/stackfolo/building-a-chrome-extension-with-manifest-v3-lessons-from-stackfolo-2fhk</link>
      <guid>https://dev.to/stackfolo/building-a-chrome-extension-with-manifest-v3-lessons-from-stackfolo-2fhk</guid>
      <description>&lt;h1&gt;
  
  
  Building a Chrome Extension with Manifest V3: Lessons from STACKFOLO
&lt;/h1&gt;

&lt;p&gt;When we started building STACKFOLO, a new-tab dashboard for developers managing multiple side projects, the timing was unfortunate in one specific way: Chrome was in the middle of deprecating Manifest V2.&lt;/p&gt;

&lt;p&gt;We had to build entirely on Manifest V3 from day one. No migration to worry about, but also no safety net of "just port this from MV2." Every decision had to work within MV3's constraints. Here is what we learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MV3 Changes the Mental Model
&lt;/h2&gt;

&lt;p&gt;If you built Chrome extensions on MV2, you are used to background pages. A background page is a persistent JavaScript context that lives as long as the browser is open. You can cache data in memory, maintain open WebSocket connections, and count on your event listeners always being registered.&lt;/p&gt;

&lt;p&gt;MV3 replaces background pages with &lt;strong&gt;service workers&lt;/strong&gt;. Service workers are not persistent. Chrome terminates them when idle, typically after 30 seconds of inactivity. They wake up when an event fires, handle it, and go back to sleep.&lt;/p&gt;

&lt;p&gt;This sounds like a minor architectural change. In practice, it rewires how you think about state management and background processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem With In-Memory State
&lt;/h3&gt;

&lt;p&gt;On MV2, you might write code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// background.js (MV2) - this worked fine&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;userProjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_PROJECTS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userProjects&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// always available&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On MV3, &lt;code&gt;userProjects&lt;/code&gt; will be empty every time the service worker wakes up from sleep. Any in-memory state is gone.&lt;/p&gt;

&lt;p&gt;The fix is straightforward but requires discipline: &lt;strong&gt;never rely on service worker memory for persistent state&lt;/strong&gt;. Everything that needs to survive across events must go through &lt;code&gt;chrome.storage&lt;/code&gt; or an external database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// background.js (MV3) - correct pattern&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_PROJECTS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;projects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// keep the message channel open for async response&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;return true&lt;/code&gt; is easy to miss and causes subtle bugs where &lt;code&gt;sendResponse&lt;/code&gt; gets called after the listener returns, silently failing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Firebase Integration: The Auth Challenge
&lt;/h2&gt;

&lt;p&gt;STACKFOLO uses Firebase for cloud sync (Pro feature). Firebase Auth works fine in content scripts and popup pages, but the service worker context presented a specific problem.&lt;/p&gt;

&lt;p&gt;The Firebase Web SDK assumes a persistent JavaScript environment. When you call &lt;code&gt;onAuthStateChanged&lt;/code&gt;, it sets up a listener that fires when auth state changes. In a service worker, that listener is gone every time the worker restarts.&lt;/p&gt;

&lt;p&gt;Our solution was to avoid relying on &lt;code&gt;onAuthStateChanged&lt;/code&gt; in the service worker entirely. Instead, we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Persist the auth token manually&lt;/strong&gt; using &lt;code&gt;chrome.storage.local&lt;/code&gt; after login&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initialize Firebase with the stored token&lt;/strong&gt; on each service worker wake-up&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle token refresh explicitly&lt;/strong&gt; rather than relying on Firebase's automatic refresh
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simplified pattern for Firebase auth in MV3 service worker&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAuthenticatedUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stored&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tokenExpiry&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;stored&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authToken&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;stored&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tokenExpiry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Token missing or expired, user needs to re-authenticate via popup&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Use the stored token for Firestore requests directly&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;stored&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The popup page handles the actual Firebase Auth UI and login flow. Once authenticated, it stores the token in &lt;code&gt;chrome.storage.local&lt;/code&gt; where the service worker can access it. The service worker never tries to maintain its own auth state.&lt;/p&gt;

&lt;p&gt;This pattern is more verbose than the typical Firebase setup, but it works reliably under MV3's constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content Script Communication Patterns
&lt;/h2&gt;

&lt;p&gt;STACKFOLO's AI Smart Save feature needs to analyze the current page content. That means the content script (which has DOM access) needs to talk to the service worker (which handles AI API calls).&lt;/p&gt;

&lt;p&gt;MV3 makes this a bit more complex because of stricter message passing rules. Here is the pattern we settled on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// content-script.js&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveCurrentPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta[name="description"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Extract main content for AI analysis&lt;/span&gt;
    &lt;span class="na"&gt;bodyText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AI_SAVE_PAGE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pageData&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// service-worker.js&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AI_SAVE_PAGE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;handleAISave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// async response&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing MV3 is strict about: you cannot call &lt;code&gt;chrome.tabs.executeScript&lt;/code&gt; from content scripts. All scripting API calls must go through the service worker. This bit us early on when we tried to inject helper code from a content script context.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Classification Architecture
&lt;/h2&gt;

&lt;p&gt;The AI Smart Save feature is STACKFOLO's most complex piece. When you save a page, we want to automatically determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which project this resource belongs to&lt;/li&gt;
&lt;li&gt;A short purpose description (why you'd reference this)&lt;/li&gt;
&lt;li&gt;A quality rating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing this inside a Chrome extension has two constraints that do not apply to regular web apps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. You cannot run AI models locally (practically speaking)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chrome extensions run in a browser context with limited compute. While the Chrome AI APIs are improving, for production use we call an external API. The service worker makes the call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The service worker has a strict timeout&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chrome enforces a maximum service worker lifetime. For AI API calls that can take 2-5 seconds, this is fine. But if we wanted to do bulk processing (saving 10 resources at once), we needed to be careful about chaining async operations.&lt;/p&gt;

&lt;p&gt;Our architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content Script
    |
    | (page data)
    v
Service Worker
    |
    | (batched or single request)
    v
AI API (external)
    |
    | (classification result)
    v
Service Worker
    |
    | (write to Firestore)
    v
chrome.storage.local (cache)
    |
    | (message back)
    v
New Tab Page (UI update)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new tab page is a Chrome Extension page (not a content script), so it has direct access to &lt;code&gt;chrome.storage&lt;/code&gt; and can listen for storage changes to update the UI without going through the service worker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// new-tab.js - listening for resource updates&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChanged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recentResources&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;renderResources&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recentResources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern keeps the UI responsive. The service worker does the heavy lifting asynchronously, and the UI reacts to storage changes rather than waiting for a message response.&lt;/p&gt;

&lt;h2&gt;
  
  
  The New Tab Page Is Different From Other Extension Pages
&lt;/h2&gt;

&lt;p&gt;One thing that catches people off guard: &lt;code&gt;chrome.newtab&lt;/code&gt; is not a standard API. Your extension provides a new tab by declaring it in the manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chrome_url_overrides"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"newtab"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"newtab.html"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is less obvious is that the new tab page behaves differently from popup pages in a few ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It loads fresh on every new tab open (no caching of the page state)&lt;/li&gt;
&lt;li&gt;Chrome gives it slightly different permissions in some edge cases&lt;/li&gt;
&lt;li&gt;Users can only have one extension override the new tab, so if you are replacing the new tab you are asking users to commit to your tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point has UX implications. We put an onboarding step early in the flow that explains the new tab replacement and gives users an easy way to disable it. Extensions that hijack the new tab without explaining themselves get bad reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  Permissions: Ask for Less, Get More
&lt;/h2&gt;

&lt;p&gt;MV3 introduced more granular permission controls. The principle is "least privilege," and Chrome will now warn users more prominently about extensions requesting broad permissions.&lt;/p&gt;

&lt;p&gt;We made a deliberate choice to avoid &lt;code&gt;tabs&lt;/code&gt; permission and use &lt;code&gt;activeTab&lt;/code&gt; instead for most features. The difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tabs&lt;/code&gt;: Access tab information across all open tabs at all times&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;activeTab&lt;/code&gt;: Access the current tab only when the user explicitly invokes the extension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AI Smart Save, the user clicks the extension icon (or uses the keyboard shortcut), which grants &lt;code&gt;activeTab&lt;/code&gt; access at that moment. We do not need to read all open tabs passively.&lt;/p&gt;

&lt;p&gt;This reduces the permission warning surface at install time, which measurably affects conversion from Chrome Web Store page to install.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Would Do Differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start with a clear storage schema.&lt;/strong&gt; We iterated on our &lt;code&gt;chrome.storage.local&lt;/code&gt; data structure several times, and each migration was painful. Treat your storage schema like a database schema. Version it from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write integration tests for the service worker lifecycle.&lt;/strong&gt; Unit tests miss the class of bugs that only appear when the service worker restarts mid-operation. Write tests that explicitly terminate and restart the worker between operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate the extension logic from the UI logic early.&lt;/strong&gt; We ended up with too much business logic in the new tab page initially, which made testing hard. The extension should be a thin layer. Logic belongs in the service worker or in shared modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building on MV3 Today
&lt;/h2&gt;

&lt;p&gt;MV3 is the present and future of Chrome extensions. The constraints are real, but they are workable once you internalize the service worker lifecycle.&lt;/p&gt;

&lt;p&gt;The biggest mental shift: stop treating the extension like a long-running server process and start treating it like a collection of event handlers. Each handler should be stateless except for what it reads from storage.&lt;/p&gt;

&lt;p&gt;If you are building a Chrome extension that needs persistent background processing, look into the &lt;code&gt;offscreen&lt;/code&gt; API (MV3 adds this for use cases like audio playback that genuinely need a persistent context). For most extensions, the service worker model is sufficient once you stop fighting it.&lt;/p&gt;




&lt;p&gt;STACKFOLO is the developer dashboard we built using these patterns. If you are managing multiple side projects and want to see how it handles AI resource classification in practice, you can try it for free.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-03-w11-growth&amp;amp;utm_content=devto-mv3-article" rel="noopener noreferrer"&gt;Try STACKFOLO free on Chrome Web Store&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>sideprojects</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My Developer Habit Tracking System: How I Use Routine Blocks to Ship Side Projects</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Mon, 16 Mar 2026 05:03:07 +0000</pubDate>
      <link>https://dev.to/stackfolo/my-developer-habit-tracking-system-how-i-use-routine-blocks-to-ship-side-projects-j0p</link>
      <guid>https://dev.to/stackfolo/my-developer-habit-tracking-system-how-i-use-routine-blocks-to-ship-side-projects-j0p</guid>
      <description>&lt;h1&gt;
  
  
  My Developer Habit Tracking System: How I Use Routine Blocks to Ship Side Projects
&lt;/h1&gt;

&lt;p&gt;I have started and abandoned more side projects than I can count. Not because the ideas were bad or because I lost motivation overnight. The pattern was always the same: I would work intensely for a few weeks, skip a couple of days, lose momentum, and never come back.&lt;/p&gt;

&lt;p&gt;Last year I decided to figure out why. The answer was not about motivation or discipline. It was about the difference between tasks and routines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Task vs Routine Confusion
&lt;/h2&gt;

&lt;p&gt;Most productivity systems treat everything as a task. "Build landing page" goes on the same list as "practice algorithms" and "review pull requests." But these are fundamentally different things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tasks&lt;/strong&gt; are one-time actions with a clear endpoint. Build a landing page. Fix that auth bug. Write the README.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routines&lt;/strong&gt; are repeating behaviors that compound over time. Daily algorithm practice. Weekly code reviews. Morning planning sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I mixed them together, routines always lost. A task like "fix the payment bug" feels urgent. "Practice algorithms for 30 minutes" does not. So the routines got pushed to "later," and "later" became "never."&lt;/p&gt;

&lt;p&gt;The moment I started tracking them separately, everything changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Routine Blocks System
&lt;/h2&gt;

&lt;p&gt;I call my approach "Routine Blocks" because it works like Tetris. Instead of a flat to-do list, I visualize my week as a grid of time slots and drop recurring blocks into them.&lt;/p&gt;

&lt;p&gt;Here is what my weekly schedule looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Weekly Routine Grid
═══════════════════════════════════════════════════════════
         Mon    Tue    Wed    Thu    Fri    Sat    Sun
Morning  [ALG]  [ALG]  [ALG]  [ALG]  [ALG]  [OSS]  [---]
         [PLAN]                              [BLOG]
Afternoon              [CR]          [CR]
Evening  [PUSH] [PUSH] [PUSH] [PUSH] [PUSH]
         [READ] [READ]               [READ] [READ]
═══════════════════════════════════════════════════════════

ALG  = Algorithm practice (30 min)
PLAN = Weekly planning session (Mon only, 20 min)
CR   = Code review on open source projects (45 min)
PUSH = Git push - commit something, anything (30 min)
READ = Technical reading - docs, articles, RFCs (20 min)
OSS  = Open source contribution (60 min)
BLOG = Write a dev blog post (90 min)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: these blocks are not tasks. I do not check them off and move on. They repeat every week, automatically. The question is never "should I do algorithm practice today?" but "it is Tuesday morning, algorithm block is up."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Visual Scheduling Beats To-Do Lists for Habits
&lt;/h2&gt;

&lt;p&gt;Three reasons this grid format works better than a list:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. You see the gaps.&lt;/strong&gt; A to-do list hides the fact that you have nothing scheduled for Wednesday evenings. A visual grid makes empty slots obvious. If there is a gap, you can fill it or keep it intentionally empty for rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. You see the overload.&lt;/strong&gt; When I first filled in my grid, I realized I had packed every single evening slot. That was clearly unsustainable. The visual format made it obvious before I burned out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. You build spatial memory.&lt;/strong&gt; After a few weeks, I stopped checking the schedule. Tuesday afternoon meant code review. It was automatic. The visual layout helped my brain create those associations faster than a text list ever could.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ONE Thing Filter
&lt;/h2&gt;

&lt;p&gt;The hardest part of routine blocks is deciding what goes on the grid. You cannot fill every slot, and not every habit matters equally.&lt;/p&gt;

&lt;p&gt;I use a filter borrowed from Gary Keller's "The ONE Thing" philosophy. Before adding a routine block, I ask one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the ONE thing I can do consistently that would make shipping this project easier or unnecessary?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For my current side project (a developer tool), the answer was clear: the single most important routine was a daily Git push. Not because every commit is meaningful, but because maintaining the habit of touching code daily prevents the "I have not opened this project in two weeks" death spiral.&lt;/p&gt;

&lt;p&gt;Everything else on my grid supports that core routine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Algorithm practice&lt;/strong&gt; keeps my problem-solving sharp so coding sessions are more productive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review&lt;/strong&gt; exposes me to patterns I can apply in my own project&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical reading&lt;/strong&gt; prevents me from reinventing solutions that already exist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekly planning&lt;/strong&gt; ensures I know what to work on during my Git push blocks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a routine does not connect back to shipping the project, it does not earn a slot on the grid.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Before and After
&lt;/h2&gt;

&lt;p&gt;Here is what my side project output looked like before and after implementing this system:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before (Q3 2025):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 side projects started, 0 shipped&lt;/li&gt;
&lt;li&gt;Average streak before abandoning: 11 days&lt;/li&gt;
&lt;li&gt;No consistent coding schedule&lt;/li&gt;
&lt;li&gt;Algorithm practice: "when I feel like it" (roughly twice a month)&lt;/li&gt;
&lt;li&gt;Blog posts written: 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After (Q4 2025 through Q1 2026):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 side projects started, 1 shipped to production, 1 at 80% completion&lt;/li&gt;
&lt;li&gt;Current coding streak: 67 days&lt;/li&gt;
&lt;li&gt;Algorithm practice: 5 days/week (missed only 4 days in 3 months)&lt;/li&gt;
&lt;li&gt;Blog posts written: 6&lt;/li&gt;
&lt;li&gt;Open source PRs: 12&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The numbers are not extraordinary. That is kind of the point. I did not become 10x more productive. I just stopped having zero-output weeks. The consistency compounded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Tips for Building Your Own Routine Blocks
&lt;/h2&gt;

&lt;p&gt;If you want to try this system, here are the patterns that worked for me:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with 3 blocks, not 15.&lt;/strong&gt; My first grid had 4 routines. I added more only after the first 4 felt automatic (about 3 weeks in).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protect your morning slot.&lt;/strong&gt; Whatever your highest-priority routine is, put it in the morning before work/meetings can steal the time. For me, that is algorithm practice. For you, it might be writing or reviewing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use frequency tiers.&lt;/strong&gt; Not everything needs to be daily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frequency tiers:
  Daily     → Git push, Algorithm practice
  Weekdays  → Technical reading
  2x/week   → Code review (Tue, Thu)
  Weekly    → Planning (Mon), Blog (Sat), OSS (Sat)
  Monthly   → Side project retrospective
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Track streaks, not perfection.&lt;/strong&gt; Missing one day is fine. Missing two days in a row is where habits die. I track current streak and longest streak for each routine. The goal is not 100% completion. It is avoiding two consecutive misses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate the grid from your task list.&lt;/strong&gt; This is critical. Your routine grid should live in a different place than your to-do list. If they are in the same view, tasks will crowd out routines again. I keep my task list in one view and my weekly routine heatmap in another.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tool I Use
&lt;/h2&gt;

&lt;p&gt;Full disclosure: I ended up building the routine blocks system into &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-03-w12-growth&amp;amp;utm_content=devto-blog6-inline" rel="noopener noreferrer"&gt;STACKFOLO&lt;/a&gt;, the developer project dashboard I work on. It started as a spreadsheet, then a Notion template, and eventually became a feature because I wanted the routine grid right in my Chrome new tab where I would see it dozens of times a day.&lt;/p&gt;

&lt;p&gt;The built-in version has a weekly heatmap, streak tracking, 50+ habit templates (algorithm practice, code review, pomodoro, and others), and time slot categories (Morning, Afternoon, Evening, Anytime). It also connects to the ONE Thing goal system, so each routine links back to a specific project goal.&lt;/p&gt;

&lt;p&gt;But honestly, the system works with a spreadsheet too. The format matters less than the principle: separate your routines from your tasks, make them visual, and filter ruthlessly using the ONE Thing question.&lt;/p&gt;

&lt;p&gt;If you have been struggling to maintain consistent habits around your side projects, try building a routine grid this week. Start with just three blocks. See if the consistency compounds the way it did for me.&lt;/p&gt;




&lt;p&gt;If you want to try STACKFOLO's built-in Routine Blocks, it is free on the Chrome Web Store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-03-w12-growth&amp;amp;utm_content=blog-cta-bottom" rel="noopener noreferrer"&gt;Try STACKFOLO free on Chrome Web Store&lt;/a&gt; →&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Why Every Developer Needs a Project Dashboard</title>
      <dc:creator>STACKFOLO</dc:creator>
      <pubDate>Sun, 08 Mar 2026 02:21:24 +0000</pubDate>
      <link>https://dev.to/stackfolo/why-every-developer-needs-a-project-dashboard-4827</link>
      <guid>https://dev.to/stackfolo/why-every-developer-needs-a-project-dashboard-4827</guid>
      <description>&lt;h1&gt;
  
  
  Why Every Developer Needs a Project Dashboard
&lt;/h1&gt;

&lt;p&gt;You have 47 tabs open. Four of them are Stack Overflow answers you might need later. Two are GitHub repos you were comparing last Tuesday. One is a tutorial you bookmarked three months ago and forgot about. And somewhere in that mess is the actual thing you were working on.&lt;/p&gt;

&lt;p&gt;If this sounds familiar, you are not alone. Developers who juggle multiple side projects deal with this chaos daily. The problem is not a lack of discipline. It is a lack of structure.&lt;/p&gt;

&lt;p&gt;A developer project dashboard can fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost of Scattered Projects
&lt;/h2&gt;

&lt;p&gt;Let's talk about what happens when your projects live across a dozen different places.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tab Hell Is Real
&lt;/h3&gt;

&lt;p&gt;According to a &lt;a href="https://www.cs.cmu.edu/~bam/papers/chi2024-tabs.pdf" rel="noopener noreferrer"&gt;2024 study from Carnegie Mellon University&lt;/a&gt;, knowledge workers keep an average of 25-40 browser tabs open at any given time. Developers tend to be on the higher end of that range because every project involves multiple contexts: the repo, the docs, the deployment dashboard, the design file, the issue tracker.&lt;/p&gt;

&lt;p&gt;The problem with tab hell is not just visual clutter. It is the cognitive cost of context switching. Every time you scan through tabs trying to find where you left off, you burn mental energy that could go toward actual coding. Research on task switching suggests it takes roughly 23 minutes to fully refocus after a context switch. Even small interruptions, like hunting for the right tab, add up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bookmark Chaos
&lt;/h3&gt;

&lt;p&gt;Bookmarks were supposed to solve this. In practice, they become a graveyard.&lt;/p&gt;

&lt;p&gt;You bookmark a useful API reference with good intentions. It joins a folder with 200 other links. Some are outdated. Some are duplicates. Most are impossible to find because you saved them with the page's default title instead of something descriptive.&lt;/p&gt;

&lt;p&gt;Browsers were built for navigating the web, not for organizing your development workflow. Bookmark folders are flat, static, and disconnected from the projects they belong to. There is no way to say "this link belongs to my e-commerce side project" and have it show up alongside your todos, commits, and deployment status for that project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources Scattered Across Tools
&lt;/h3&gt;

&lt;p&gt;Here is a typical developer's project ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; for code and issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notion or Google Docs&lt;/strong&gt; for notes and specs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Figma&lt;/strong&gt; for design references&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel or Netlify&lt;/strong&gt; for deployments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack or Discord&lt;/strong&gt; for team communication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twitter/X bookmarks&lt;/strong&gt; for inspiration and tutorials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube playlists&lt;/strong&gt; for video tutorials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tool does its job well. But none of them give you a single view of what matters for a specific project right now. You end up playing a daily game of "which app was that in?" and it is exhausting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Project Dashboard Actually Solves
&lt;/h2&gt;

&lt;p&gt;A developer project dashboard is not another project management tool. You do not need a replacement for Jira or Linear for your side projects. What you need is a single place that ties together the context around each project.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. One View Per Project
&lt;/h3&gt;

&lt;p&gt;Instead of mentally mapping "these 8 tabs are for Project A and those 6 are for Project B," a dashboard gives each project its own space. Your resources, links, notes, and progress all live together. When you switch projects, you switch contexts cleanly.&lt;/p&gt;

&lt;p&gt;This sounds simple, but the impact is significant. No more searching. No more "wait, which tab was that?" You open your project view and everything is there.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Reduced Context Switching
&lt;/h3&gt;

&lt;p&gt;When your project context is pre-loaded, you eliminate the startup cost of getting back into flow. You do not need to reconstruct your mental model of where things are. The dashboard remembers so you do not have to.&lt;/p&gt;

&lt;p&gt;For developers managing 2-5 side projects alongside a day job, this is the difference between making progress on a side project in a 30-minute window versus spending 15 of those minutes just finding where you left off.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Resources That Stay Organized
&lt;/h3&gt;

&lt;p&gt;The best project dashboards let you save resources directly to a project context. Found a useful tutorial? Save it to the relevant project, not to a generic bookmark folder. Need to reference an API doc? It is right there with the rest of the project's resources.&lt;/p&gt;

&lt;p&gt;This project-first organization means resources are useful when you need them, not buried in a global list you will never scroll through.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Visibility Into Your Own Progress
&lt;/h3&gt;

&lt;p&gt;When you are working on multiple projects, it is easy to lose track of which ones are moving forward and which are stalling. A dashboard that shows your recent activity, commits, or task completion gives you an honest picture of where your time is going.&lt;/p&gt;

&lt;p&gt;This is not about productivity guilt. It is about making intentional choices. If you can see that you have not touched Project C in three weeks, you can consciously decide to either pick it back up or set it aside.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Look for in a Developer Project Dashboard
&lt;/h2&gt;

&lt;p&gt;Not all dashboards are built for developers. Many productivity tools are designed for managers or teams, not for someone who needs quick access to a GitHub repo, a localhost URL, and an API reference at the same time.&lt;/p&gt;

&lt;p&gt;Here is what matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project-based organization&lt;/strong&gt;: Resources, links, and notes grouped by project, not by type&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low friction to save resources&lt;/strong&gt;: If it takes more than two clicks to save a link to a project, you will stop doing it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser-native&lt;/strong&gt;: Developers live in the browser. A dashboard that shows up in your new tab is always accessible without opening yet another app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration with your actual workflow&lt;/strong&gt;: GitHub activity, commit history, and other signals that reflect real progress&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: A dashboard that takes 3 seconds to load defeats the purpose. It needs to be instant&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How STACKFOLO Fits In
&lt;/h2&gt;

&lt;p&gt;This is exactly the problem we built &lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=blog&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-03-seo-content&amp;amp;utm_content=blog-cta-inline" rel="noopener noreferrer"&gt;STACKFOLO&lt;/a&gt; to solve.&lt;/p&gt;

&lt;p&gt;STACKFOLO is a Chrome extension that turns your new tab into a project dashboard. Each project gets its own space with resources, links, and context. The AI Smart Save feature automatically categorizes web resources into the right project when you save them. Your GitHub commit timeline shows up alongside your projects so you can see real activity at a glance. And because it is a new tab extension, it is always one keystroke away.&lt;/p&gt;

&lt;p&gt;The free plan gives you up to 100 saved resources and 30 AI-powered saves per month, which is enough to try the workflow and see if it clicks for you.&lt;/p&gt;

&lt;p&gt;No more tab hell. No more bookmark graveyards. Your projects, organized in the one place you already open dozens of times a day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;The developer project dashboard is not a new category of tool. It is a recognition that developers who build multiple things need a better home base than 40 open tabs and a bookmarks folder they never check.&lt;/p&gt;

&lt;p&gt;If you have been feeling the friction of scattered projects, the fix is not "be more organized." It is having a system that makes organization the default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/stackfolo/gakjkkjgbekgmdkijbgdpdmmhenjejpb?utm_source=blog&amp;amp;utm_medium=article&amp;amp;utm_campaign=2026-03-seo-content&amp;amp;utm_content=blog-cta-bottom" rel="noopener noreferrer"&gt;Try STACKFOLO free on Chrome Web Store&lt;/a&gt;&lt;/p&gt;

</description>
      <category>developerproductivity</category>
      <category>projectmanagement</category>
      <category>chromeextension</category>
      <category>sideprojects</category>
    </item>
  </channel>
</rss>
