MoreRSS

site iconAdam FortunaModify

A full-stack product developer living in Salt Lake City, UT.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of Adam Fortuna

Converting Adamfortuna.com from Next.js to Astro with a Headless WordPress CMS

2025-02-09 07:02:36

This blog has undergone a lot of changes over the years. It was WordPress for many years, Jekyll, OctoPress, Middleman, and most recently Next.js with WordPress.

In 2024, I fell out of love with Next.js. I was a huge proponent of it for years. Hardcover is built on it (although we’re migrating to Ruby on Rails + Inertia.js) and I even started Nextjsbits.com, a blog about Next.js. I wrote a bunch of blog posts about Next.js, and I posted on the Next.js subreddit. In other words, I thought it was pretty great.

We switched to the Next.js App directory almost as soon as that was an option. I was so excited to use React Server Components that I waved away all the beta warnings and went full speed ahead. And it worked! Functionally, at least.

Slowly, problems started to sneak in. Our build time spiked, sometimes taking a minute locally for a route that should take a fraction of a second. Our Vercel bill grew from $20 a month to $500 due to the switch from client-side data loading to server-side loading. I (incorrectly) thought I understood how caching worked, only to later realize that nearly nothing was being cached – but even then I didn’t have insight into what was actually cached.

There were problems. The development experience was slower. The production experience was slower. Debugging it was slower. Expenses were higher.

All of these problems have solutions. They’re not inherent to Next.js, but they are (or at least were) difficult to avoid – even for someone who read the caching article on Next.js’s site at least 50 times.

I’ve since spent a bunch of time trying to understand what was wrong. Using turbo for local development might be possible with the latest version of Next.js – but by the time that was released, Hardcover’s migration was nearing the finish line.

By October of 2024 I was frustrated to the point I was looking for other options. Once the Hardcover rewrite is complete, I’ll share more about that process.

In November 2024, after the election, Vercel’s CEO, Guillermo Rauch, posted on X about his support of Trump. This was around the same time Sticker Mule’s CEO made similar statements.

Your attention and your spending are votes. While I know Next.js is a project with many amazing developers, Vercel is a business and the backing force behind Next.js.

I decided to start removing Next.js from my projects. I shut down Next.js Bits. I migrated Hardcover from Vercel to Google Cloud Run. Hardcover is being migrated away. And lastly, this blog is now running on Astro!

Migrating from Next.js to Astro

After seeing Astro on the yearly JavaScript survey with a high satisfaction score, it drew me in. When I realized their official documentation had a section on Headless WordPress & Astro, I knew it was a perfect fit.

The big difference between Next.js and Astro (or my specific implementation) is how pages are rendered. With Next.js, pages are all rendered when they’re first requested. For this blog, every page is rendered to static HTML at build time. That means it’s super fast!

There are downsides to this. When I write or edit a new post, it won’t be immediately available until a rebuild of the entire site is triggered. It also means that comments (using WordPress) aren’t an option. That’s something I still need to figure out. 🤔

When I started searching for “astro WordPress headless cms”, a wealth of videos came up! This also led me to this great Astro starter template.

I decided to start from scratch with npm create astro@latest and go from there.

Converting Next.js Pages to Astro

One of my first steps is making a list of the routes needed. There were a few more routes I haven’t moved over yet (ex: books read, photo posts).

  • / – Landing page for fun.
  • /projects – All the projects I’ve ever worked on, powered by WordPress.
  • /blog – List of all blog posts across all of my projects’ blogs.
  • /blog/projects – List of all projects.
  • /blog/projects/:project/:page – Paginated list of posts by project
  • /blog/all/:page – Paginated list of posts.
  • /blog/tags – List of all tags.
  • /blog/tags/:tag/:page – Paginated list of posts by tag.
  • /newsletter – Form to sign up for my newsletter (submitted to Sendy).
  • /newsletter/thanks – Redirect after signing up.
  • /:post – Single post or page corresponding with a WordPress URI.

That’s it! Not too many. I started converting everything on Tuesday, and by Saturday, everything was working!

The hardest part of the migration was moving React.js components into Astro components. Fortunately, only a few places require client-side code (namely, the homepage and the projects page).

Most of these are relatively simple like the Article component. Other more advanced components I kept as React (for now), like the Projects Listing component. Fetching data happens in Astro, then the Projects are passed to React for interactivity.

Fetching Data from WordPress

Fortunately, nothing changed on the WordPress side. I moved over all of my previous fetch GraphQL client, TypeScript types and all GraphQL queries.

I made the decision with this blog to list posts from adamfortuna.com, hardcover.app and minafi.com – three blogs I’ve spent a bunch of time on. However, only individual posts from adamfortuna.com are visible.

This means that when it comes to listing posts, or posts by tag, I need to grab posts from all three blogs and sort them by date.

The solution for this is to hit all three blogs, parse the results and sort them. The code for this is a bit hectic, but does the job. Most of these functions accept an array of projects to fetch from, that way if I want to add another blog later I can easily add it.

WordPress can allow GraphQL access without authentication, but certain fields won’t be available. The most important one is excerpt as regular text. I use this in the meta description and show it on the blog listing page for highlighted posts. That meant authentication would be needed.

I created tokens for each blog that represent the username and password, which are then set as environment variables.

Astro Pagination

My favorite part of the migration was using Astro’s pagination. Each paginated page is incredibly simple. The getStaticPaths method provides a paginate function which can be used to create multiple paginated pages from the same array of data. You don’t even need to slice the array!

Pagination with nested routes takes a little more work. For example, /blog/projects/:project/:page. This page needs to use the array of projects and gets all posts for each one then paginates them. The same technique is used on the Tag page.

Astro Workarounds

There were two parts I needed to change in order to work well with Astro and static generation.

The first was on the posts by tag page. When Astro tries to load the route /blog/tags/:tag/:page, it has to do a lot of work. It loads all tags, then it hits all three blogs to get all tags for each one. With 70 tags (so far), that means over 200 requests. This wouldn’t be a problem, but doing so using Promise.all meant DDOSing WordPress with 70 requests at a time. 😅

I switched to doing these in serial rather than parallel and it seemed to do the trick.

The next problem was that development was slow due to all of these API calls. This one was easy enough. I cached these saved values to a local variable and used those instead. If there’s a better way to do this with Astro, please point me in that direction.

The last major problem was updating Tailwind.css from version 3 to 4. The process went smoothly once I realized the @config ‘../../tailwind.config.js’ option in CSS file. Previously, I used the @screen md {} option in there to limit changed to @media(min-width: theme(--breakpoint-md)) { }.

Hosting

A few months ago I switched from Vercel to Netlify, and have been loving it. I haven’t tried it for anything big, but for my blog it’s been wonderful.

I set up Astro on there, and it worked on the first build!

What’s Next

This has been a fun project so far. There are a few things I’d still like to do next.

  • ✅ Trigger a rebuild when something changes in WordPress
  • Figure out what to do about Comments and Webmentions
  • Add a book page showing what I’ve read or reading
  • Add a movie page showing what I’ve watched.
  • Same for TV shows.
  • Add a list of hikes, maybe using something like this.
  • Add back my photo posts. I’ve written a few in WordPress already.
  • Add dark mode
  • Make the homepage even more fun!

Updates!

Rather than writing a new post, I’m going to update this one as I tweak things.

Trigger Updates When WordPress Changes

It didn’t take long before I needed to fix a spelling error in this post. I don’t want to spend 15 minutes rebuilding the site to see those kinds of changes. Instead, I want them to be available as soon as possible!

The solution is to rely on Netlify for server-side generation (SSR).

That started with using the @astrojs/netlify library. While it’s possible to generate every post every time it’s accessed, I’d rather cache as much as possible for as long as possible.

After configuring Netlify with Astro, the next step was to set the right headers for each page.

// The browser should always check freshness
Astro.response.headers.set("cache-control", "public, max-age=0, must-revalidate");

// The CDN should cache for a year, but revalidate if the cache tag changes
Astro.response.headers.set("netlify-cdn-cache-control", "s-maxage=31536000");

// Tag the page with the book ID
Astro.response.headers.set("netlify-cache-tag", `post-id-${article.id}`);

The last one will use the dynamic post ID from the given post from WordPress.

To invalidate this, I needed to add a webhook that WordPress would hit, at src/pages/api/webhook.json.ts. This is the URL that’ll be hit whenever a new post is created or a post is updated.

export const prerender = false

import type { WordPressClientIdentifier } from "@/types";
import { purgeCache } from "@netlify/functions";

function sourceToProject(sourceUrl: string): WordPressClientIdentifier | null {
  if(sourceUrl === "https://adamfortuna.com/") {
    return "adamfortuna";
  } else if(sourceUrl === "https://minafi.com/") {
    return "minafi";
  } else if(sourceUrl === "https://hardcover.com/") {
    return "hardcover";
  } else {
    return null;
  }
}

export async function POST({ request }: { request: Request }) {
  try {    
    // See below for information on webhook security
    if (request.headers.get("x-wordpress-webhook-secret") !== import.meta.env.WORDPRESS_WEBHOOK_SECRET) {
      return new Response("Unauthorized", { status: 401 });
    }

    const body = await request.json();
    const { post_id } = body;    
    if(!post_id) {
      return new Response("No Post ID", { status: 401 });
    }

    const project = sourceToProject(request.headers.get("x-wp-webhook-source") || "");
    if(!project) {
      return new Response("No Project", { status: 401 });
    }

    const postTags = Object.keys(body.taxonomies?.post_tag || {});
    const tags = [
      `post-id-${post_id}`,
      `blog/projects/${project}`,
      'blog',
      'blog/all',
      ...postTags
    ]
    await purgeCache({
      siteID: import.meta.env.NETLIFY_SITE_ID,
      tags,
      token: import.meta.env.NETLIFY_TOKEN
    });
  
    return new Response(`Revalidated entry with id ${post_id}`, { status: 200 });
  } catch(e) {
    return new Response(`Something went wrong: ${e}`, { status: 500 });
  }
}

This ties in with all of the pages that could have this post – the main listing page, the all blog posts page, the posts by projects, and the tag pages. Each of these has their own cache key that corresponds with this callback.

To create the callback, I installed the WP Webhooks plugin, which works well for this. It also allows you to add custom headers to your requests. I added a x-wordpress-webhook-secret header that it sends over and I check for.

Next, I needed to grab my NETLIFY_SITE_ID from Netlify, and also create a personal token (NETLIFY_TOKEN). I added these locally and on production.

However, the caching I’d previously added conflicted with this. I disabled it, but then the initial build went too slow. The solution was even more simple: change routes that need dynamic generation to start with the line:

export const prerender = false

With this, these pages won’t be generated when deployed but will be cached when rendered.

Side note: I went down another route where I attempted to build these at deploy time but then expire them with a webhook call. That didn’t work. I needed to add this prerender = false code in for it to work.

New House, New Rules

2025-02-05 09:00:42

Later this month, we’re moving from the apartment we’ve lived in for the last 8 years to a house! It’s an exciting time. We’re still fixing and improving a few projects, but it should be mostly set to move in.

Whenever I go on a trip, I like to use that as an excuse to change my routine. It’s a time when my schedule seems the most flexible. I’m no longer evaluating things daily, allowing me to change my plans with a clearer view of the future.

I’m using the upcoming move as another chance to reset my routine and figure out what I want to leave behind.

New Rules

None of these new rules are focused on maximizing productivity or physical fitness. The focus is on feeling healthy. This includes not feeling as anxious about everything happening while still being healthy enough to protest, contact representatives, and support people in my life who need someone to lean on.

Mental Health

🛑Stop using anonymous social media (TikTok, Reddit, Reels, YouTube Shorts). Any social media you can scroll forever, and it’ll keep feeding you new content.

🛑Stop picking up my phone in the morning. I’d like to not even touch it until I’ve at least worked out and read a little.

🟢Start reading in the morning. Rather than plugging my brain into the news, I will read more books. I’ve been doing this on and off for the last month, but lately, doom scrolling has won out more days than not.

🟢Switch to pre-selected news sources. That includes The Salt Lake Tribune, WIRED, Aaron Parnas, and a few others on BlueSky.

Physical Health

🟢Continue going to the gym 3x a week on Monday, Wednesday, and Friday from 6 am to 8 am.

🟢Start going for a walk every day. It doesn’t matter how long it is. Our new house is close to a park, which I imagine I’ll get to know even better than I already do (I trained for my marathon there and already know it well).

🟢Start doing cardio 2x to 3x a week in the morning. I’ll plan to start with 2x and see increasing it to 3x. This could be a Peloton ride or, a run, a hike or anything else that gets my heart rate going. If I don’t do this when I first wake up, the likelihood of this happening decreases fast. 😅

Diet

🛑Stop drinking any alcohol unless it’s a special occasional (Super Bowl) or I’m out socially with friends. Last year for ~6 months I mostly stopped drinking, but since November I’ve been having the occasional cocktail or beer at night.

🛑Stop any THC consumption on multiple days in a row. I never vaped or took edibles until my 30s, and I’m tremendously grateful for past me for that. Doing so negates any desire to be creative or even play games. Instead, I want to lay around on my phone and watch TV. I will start with this change, but I’d like to cut this out entirely – except on weekends.

Fun

🟢Start playing more video games! Somehow, in the last few years, my attention has shifted from video games to news and social media for entertainment. Playing video games is much healthier and is a habit I’d like to restore.

🟢Start playing more board games, especially with friends. We love board games, but haven’t played nearly enough of them lately. Having a small apartment doesn’t make it easy. We have a Desden Board Game Table set to be delivered this summer, with a smaller 4-person IKEA table for now. I love that we’ll now have a place to actually play games that’s now our kitchen island.

Personal Projects

🛑Stop working on Hardcover outside of working hours. With the new house, I’ll have a dedicated office. I plan to consider that “the place” where I work on Hardcover. If I’m not in there, then I won’t worry about work.

🟢Start dedicating more time to personal projects! I have a tendency to let projects take over my life. It’s happened with Code School, Minafi, and Hardcover. With the new arrangement, I’d like to dedicate some of the “social media & news time” to doing more creative projects. I’ve already mentioned some of these on my Now page, and I’m excited to work on them (especially the Astro conversion of this blog!).

🟢Start gamifying progress. Some of the most productive times in my life were when I was actively tracking what I was working on. For a while, this happened on lineofthought.com, my now-defunct tracker. I have a plan on how to restart this, while also using it to learn some more about Swift and iOS programming. In the meantime, I’ll keep tracking using Exist.io.

Civic Action

🛑Stop supporting any large corporation that acts against my interests and those of a stable democracy. This will mean buying local much more, and cutting services where the money is going towards causes I don’t support. I’ve always done this to some extent, but I’ve turned a blind eye to some based on convenience or entertainment. That’s no longer the case.

🟢Start calling my representatives every week if there’s something that needs to be addressed. Even though I’m in Utah, I can still be an annoyance.

🟢Start becoming more involved in local politics. I have a long ways to go on this one. We’ve been to a bunch of marches, and vote in all local elections, but we’d like to do more. A new food Coop is opening a few blocks from our new house and has monthly meetings. The people we’ve met there seem very like-minded.

Relationship Health

🟢Start back with weekly, scheduled date days/nights with my wife. We’ve done this in the past, but between the move, holidays, travel and election news, we’ve gotten out of the habit. With the new house we’d love to explore everywhere we can walk to – which will provide many fun outings!

🟢Start having smaller get-togethers to go along with the bigger group ones. Meeting with friends one-on-one or just getting together for a short time. I tend to focus on large group outings that last multiple hours and leave me socially drained. Smaller get-togethers – in person and online – would create deeper connections with friends.

🟢Start or join a group that meets at Liberty Park! This is the park right by our house. I plan to go there a bunch – on walks and runs, to walk our future dog. I’d also love to have an excuse to go there socially more often.

“Don’t Change Too Much At Once”

This is common advice. It can also be wrong.

For example, if you’re trying to replace one activity with something else (like replacing social media with reading), you need to stop one behavior and start another one.

A few years ago I read Cal Newports Digital Minimalism. Most of the book talks about doing a “digital detox” – stopping all use of social sites. After trying a detox myself, I noticed it lacked much advice on what to replace that time with! It’s important to have things you’re excited about to substitute in.

Instead of reaching for your phone when you have a few free minutes, you’ll need to create a new behavior. Reach for a book, pick up a Nintendo Switch, or read your RSS feed.

I’m considering February a trial period for any of these changes I can put into place now. Even just two days with less news consumption has given me enough time to write this post!

Let’s see what a month looks like.

My 2024 Year in Review

2025-01-01 08:00:00

I’ve written a “year in review” post for the last fourteen years. I highly recommend you try it. It’s a time capsule that lets you reflect on the past year, appreciate parts of it that were great, and develop a plan for the next year. You can view any of the past 14 years’ posts here: 2010,  2011,  2012,  2013,  2014,  2015,  2016,  2017,  20182019, 2020, 2021, 2022 and 2023.

This felt like an in-between year. I didn’t undergo massive personal changes or life-changing injuries (like tearing my ACL in 2022). When I got into a routine I could stick with, I saw progress toward my goals and a massive sense of achievement. There are so many things that can go wrong, but this year things just seemed to go right.

My top themes of the year were personal fitness & health, Hardcover, and house. 🏡

I focused a bunch on personal fitness & health. After spending 2023 in physical therapy, in 2024 I started hitting the gym more (3x a week), working with an online personal trainer, and tracking calories (using the LoseIt app). I ended up losing 20 lbs (170 lbs → 150 lbs)! According to my body composition scale, I put on 10 lbs of muscle too. Having someone online to be accountable to helped keep me on track. Since November, I’ve slowed my pace and put a few pounds back on, but I’m also lifting even heavier at the gym, so some of it should be muscle. A few of my highlights have been hitting 570lbs on leg press, 110lbs on dumbbell bench press and lots of body weight dips (15 reps for each of those) 🤞

On the Hardcover side, a lot happened. We grew from 5k users to 23k. From 40 subscribers to 215. From not profitable to maybe profitable. 🙌 We launched a redesign, updated progress tracking, Letterbooks, reading journals, survived a scrapping attempt, planned advanced stats, acquired another site (which fell through) and so much more. I spent on average 25 hours a week working on Hardcover. We’re planning a big update for January I’ve been working on for the last 3 months.

In September a house went up for sale on my daily walk route in the Avenues of Salt Lake City that made me want to go and see it. It was a somewhat crazy house that we saw with a realtor, but it was both outside our price range and needed too much work. We continued looking, got under contract for one that fell through (“it’s falling in on itself” – our inspector), and eventually found a place we love in November, 2 days after we returned from our trip. We put in an offer, and closed on the house on Friday, December 27, 2024! 🥳 There are a few things to do before we move in, but it’s close to move-in ready.

Having a routine was a key part of this year’s enjoyment. Since leaving my job 6 years ago, I’ve tried lots of different schedules. I don’t see that changing anytime soon. My routine this year has revolved around a few keystone habits: Gym (6-8 am, MWF), Peloton (8 am, TR), run (R), allergy shots (M), errands (M), Hardcover Live (W), Date day (R), Takeout date night (F), gaming with kids (Sun), Video Chat with friends (W).

I’ve identified many things I want to learn and dedicated quite hours to them. These include deploying websites using Kubernetes, Tensorflow & related machine learning techniques, React Native for mobile development and automating workflows using Make and AI. To my surprise, the technologies I learned the most about ended up being Inertia.js and Kamal – two pieces I’m using right now for the Hardcover migration from Google Cloud and Heroku to Digital Ocean. I wouldn’t call myself an expert in any of these, but I’ll continue learning as I go.

Even good years have down notes. We said goodbye to 3 more friends who moved away from Salt Lake City. I spent too much time on TikTok and Reddit, which meant less reading or learning. I was constantly stressed out about Hardcover. Trying to grow it, fix bugs, and keep plates spinning while trying to enjoy learning has been stressful. I felt disorganized for much of this year – likely a byproduct of misaligned priorities. Someone was elected who I don’t support (putting it mildly here).

The 2024 US Presidential election topped the news. Trump was found guilty of 34 felonies. The Paris Summer Olympics gave us breakdancing.

My 2024 Month By Month

A few years ago, I started doing a monthly breakdown. I love being able to look back and see what I thought was most important each month.

January: Sundance Film Festival, Jazz Game.

February: Apple Vision Pro, Superbowl with friends, Broadway Rave, Comedy Church, our 18-year anniversary, Dune 2.

March: Oscar Party, trip planning, librarian updates on Hardcover.

April: South Korea for two weeks during cherry blossom season! Started working out with an online personal trainer. Ski & Snowboard lesson with Marilyn.

May: Hardcover redesign and Letterbooks. Metric concert. My 42nd birthday! Started allergy shots. Saw Death Cab for Cutie, The Postal Service, Belle and Sebastian and TV Girl at the Kilby Block Party Concert. Furiosa. Eurovision.

June: Fortuna Family reunion! Friends moving away from SLC.

July: Deadpool & Wolverine. Pie and Beer day. Jewel and Melissa Etheridge concert at Red Butte Garden. Paris Summer Olympics. Retro games tournament for friends birthday party.

August: Marilyns Birthday vinyl, tacos and dinner with Marilyn. Paint night with Marilyn. Pink Martini Concert at Red Butte Garden. SLC Soccer game.

September: Utah JS Conference, Atsuko Okasuka comedy show, Eat Drink SLC, house hunting, researching SBLOC loans, Fanx Convention.

October: Offer on the house (didn’t go through), trip to Barcelona, then cruise to Portugal and Morocco.

November: Election, accepted offer on house, Outlander, Hardcover migration, Kevin Smith, Thanksgiving day parade with mimosas and dinner with friends.

December: Dragonsteel convention, cozy Christmas, dinner and Christmas windows at The Grand America, white elephant exchange, closed on the house! 🥳

Yearly Favorites

Favorite Spot I Visited: Seoul in South Korea! We spent two weeks exploring the city, going to different districts and getting a feel of the city. The older I get, the more I enjoy going deep in a specific area rather than exploring a wide range. I’d like to go back again and spend time in Busan, Jeju and even more time in Seoul.

Favorite Meal: We went on a Seoul food tour, which was easily the best food I’ve ever been on. We were guided through more than a dozen stops, trying dishes featured on Netflix and the best friend chicken I’ve ever had. Marilyn and I had a romantic, fancy dinner at Table X for our 18-year anniversary.

Favorite Video Game I played: This year I didn’t play as many games as past years. I spent more time with my old favorites rather than start new ones. That included Stardew Valley 1.6, replaying Hollow Knight, and Overcooked.

Favorite Board Game I played: Terra Mystica was a fun new one I played with friends and then started playing on Steam. Marilyn and I played a TON of Wyrmspan – the successor to Wingspan. I might even say I prefer to Wingspan. 🫢

Favorite Concert: Jewel and Melissa Etheridge was great. Metric was fun.

Favorite Live Event: Going to Marilyns first Utah Jazz game, Chris Harwick’s comedy show, watching Eurovision live, Kevin Smith Live.

Favorite Hike: During our trip to Seoul, we had one of the most amazing and memorable hikes I’ve ever been on. Led by a folklore professor who moved from Canada to South Korea, we visited shamanic sites, ancient ramparts, and Buddhist temples while listening to mythic stories before enjoying a delicious post-hike meal together with some Mogui.

Favorite Movies: My 5⭐ movies for this year include Dune 2, It’s What’s Inside, Your Monster, Furiosa, and Monkey Man.

Favorite Shows: House of the Dragon, Shogun, Fallout, Three Body Problem (the Netflix US one), X-Men ’97, True Detective: Night Country, Fargo S5, Silo, Outlander, Dark Matter, Dune Prophecy, Shogun.

Favorite Podcasts: I’ve mostly stopped listening to podcasts and switched to audiobooks. Search Engine is one of the only ones I’m currently on.

Favorite Books: Reread The Three-Body Problem Trilogy (+ the 4th book by another author), all of the Berserk Manga, Monstress, Before We Say Goodbye (Before the Coffee Gets Cold #4), Lessons In Chemistry, The Creative Act, Convenience Store Woman, Iron Widow, The Tainted Cup, Funny Story, Starter Villain, Invincible (the comic), the entire A Court of Thorns and Roses series. 😂See all of my favorites here.

Favorite new programming discovery: Kamal for deploying Rails apps has given me the confidence to move off Heroku finally. That opens up a ton of possibilities for where and what I can host.

Favorite Project: Hardcover, of course. 🙂

Favorite Course or Education Experience: Learning Kubernetes was fun, but the courses weren’t the best. I enjoyed some random Youtube videos to better understand python data science which were more helpful than courses I’ve tried to take that focus so much on math and not on how to use Python to solve them.

Noteworthy Changes this Year

There are many things I started this year where the payoff will be in 2025: Hardcover migration, allergy shots, and buying a home. It’s felt like I worked a lot on things this year to have an even better 2025. Fortunately, the work was enjoyable.

There were some times this year when my stress level peaked higher than it has in the past few years. It’s sometimes tough to know if it’s because I’m pushing myself too hard, or just taking on hard challenges. I’d like to write and journal more in 2025, which will help relieve some of the pressure.

How’d I Do On My 2023 Resolutions?

✅Get a dog! – I started getting allergy shots in April, finished them in October, and now only need to get one a month for maintenance. With the move coming up, we decided to hold off on bringing in a new family member until we’re settled in the new place. I’ll still consider this as “done” as we did what we wanted – which is prepare for it.

✅Traveling to South Korea! – The two-week trip was so much fun! Food tours, hikes, cafes, temples, cocktails, shopping and sooo much good food.

✅Hardcover is growing! – We grew from 5k members to 22.5k in a year, which is amazing. If we 4x our pace again in 2025, we’ll hit 100k members. 😱

✅Make fitness fun – I very much enjoyed going for walks after lunch, and even going to the gym earlier by getting up at 6 am. I thought I was done waking up early when I didn’t have to, but it’s been nice.

🤷Balance consumption, creation and movement – I balanced movement. 😅 But then spent way too much time on Reddit and TikTok this year. When Reddit starts telling you your streak is 75 days maybe that’s a good indicator that you’re on there too much.

✅Plan for fun – We reserved Thursdays for dates most of this year. It was great having a dedicated day for that to put down work and focus on just having fun and being tourists in our own city. We fell of that schedule in November, but want to pick it up again.

Overall I’m happy with these goals and the progress for the year. They weren’t as specific as some year’s goals, but when I think about the gains I made in each area, they feel right.

What’s Next for 2025?

I wrote many parts of this post ahead of time, but I waited until the beginning of 2025 to write this section. Some years, I set a theme for the year.

For 2025, I’ve decided on one thing that inspires me: Now. It’s about not overthinking and overplanning and just making progress now. Done is better than perfect. Routines form because you take repeated action, not because you plan them perfectly. That’s the mindset I’m trying to instill into my brain.

It doesn’t mean that I can’t also relax, read, spend time on social media and even bed rot occasionally. But at those times when I’m relaxing and wondering, “Should I do X?” The answer is yes; if I’m wondering that, then I should do it. I trust myself to use this to spur action while giving space for relaxation.

Create a Hygge Home – Hygge is a Danish and Norwegian word that describes a feeling of contentment and coziness. That’s the feeling I’m hoping to create in the new place. I want to feel relaxed, warm, and not cluttered.

Play lots of games (board and video) – I love playing board games. In college one of the first websites I created with a Settlers of Catan League for my friends and I to track our gaming. With the new house, I’m most excited about hanging out with friends more and playing games (and playing them together with Marilyn). We even ordered a Dresden Gaming Table for the house that I can’t wait to try! My focus will be on playing games I already own to start before getting new ones. 😅

Welcome a dog – Once we’re settled, we’re excited to welcome a dog into our lives. I’ve been spending time with friends dogs and confirmed that I don’t die, which is a good sign. 😂

Write at least one post here a month – Writing helps me relieve anxiety. The downside is having another task can cause anxiety. Rather than trying to focus on writing something world-changing, I’d like to just write something. Even if it’s just a life update.

Work on a side project (tech-specific) – As much as I love Hardcover, I want to have at least one other project to work on. There’s something that happens when you can toggle between projects that results in both of them being better because of it. This past year I, focused almost exclusively on Hardcover. I have a few ideas for this, but I still need to narrow it down. It’ll probably be one of these (or all 😅): Line of Thought journal (iOS app), adamfortuna.com migration from Next.js to Astro, Raspberry pi connected to lights. The last one is an idea in my head to create a data visualization with a hundred square lights that can both react to sound or set it to different modes (relaxing, active, etc). Still more planning, but like the idea.

Continue learning Japanese – I’m putting this one here one more time this year. I’ve started thinking about going on a work trip to Japan in 2026 for a month – maybe even with my cofounder Ste for part of it! It wouldn’t be a tourism-focused trip, but more work and routine focused in a new environment. Having this trip in my mind inspires me to learn more.

Continue enjoying fitness – I was more focused on this than usual for 6 months of 2024 while working with a trainer. I found that fun, but it was also emotionally taxing to track everything I ate and workout 6 times a week. After that experience, eating mostly healthy and working out 4-5 times a week feels like a vacation. 😂 I want to continue doing that, while mixing things up so I keep having fun. I’m excited that we’ll have a park a block away from us that I can run at too! I’ll likely start running more just from the proximity there. There’s another gym within walking distance that has Olympic lifting platforms. I’d to to get back into that if it works out, but if not I’ll find other ways to have fun.

Grow Hardcover to ramen profitability – This is a bit of a scary one. 😅 Hardcover made $1,274 in December, which is amazing. My dream it to continue working on this project for many years, but for that to happen we’ll need to be able to support our lifestyle with it. Fortunately, our expenses are low, so it doesn’t need to generate much income. My dream is to be able to live a life supported by side projects that I love working on. I already love working on Hardcover, and if I can turn it into my source of income, that would be a dream come true. 🥳

Thanks for Reading

Whew, that was a lot. 2600 words, a lot. 😂 Thanks for reading, and have a great 2025!

My Second Term Plan

2024-11-07 07:06:52

Like many Americans, I woke up to a different world than I was expecting this morning. While I initially compared this feeling to 2016, it felt a lot more like 2004 for me. In 2004, Bush was reelected – a vote for his politics and brand of governorship that America wanted more of – even though I couldn’t stand him.

I spent over 12 hours watching the news, reading Reddit, and watching TikTok yesterday. It was the most I’ve doom-scrolled in quite a while, and it’s not something I’d like to make a habit of.

This comes immediately after my wife and I got back last week from a 16-day trip to Barcelona, Spain, and a cruise (Barcelona, Spain → Lisbon, Portugal → Porto, Portugal → Tangier, Morocco → Cadiz, Spain → Barcelona, Spain). During the cruise, I was utterly disconnected from the internet. I couldn’t remember the last days I had zero internet use.

Whenever I get back from a trip, I try to change my routine immediately. Fortunately, it coincides with when I want to turn off the news.

I’ve found the best times to change are when I have no clear routine in the first place. When I got back from my two-week Korea trip earlier this year, I started working with an online personal trainer, which was an incredibly beneficial change.

During the trip, I started brainstorming changes I wanted to make in my day-to-day life. Here’s what I came up with:

Redefine My Relationship with News and Social Media

For me, this means Reddit and TikTok. Both are platforms I can scroll on for hours. It’s unhealthy even in the best times. Now, in the time after the election, I know it’s going to be rough.

The time leading up to the 2016 election, and pretty much his entire first term, was a slow boil to see how much news and information I could take in. I’m following Kamala’s advice and not going back to that.

The goal of this would be:

– Completely stop using Reddit, TikTok and The New York Times (Only use TikTok for Hardcover).
+ More time reading books. I’m excited about this one! I read 2.5 books during my vacation and already feel my ability to focus for long stretches increasing.
+ More time writing blog posts
+ More time in general for other things

I’m not sure how I’ll keep myself informed about the news in a healthy way (any recommendations for that). I aim to spend more time on other social media (Mastodon, Facebook, Instagram, Threads). I suspect I’ll hear enough about what’s happening through those without relying on Reddit/NY Times.

Continue Learning Japanese

I fell out of this habit sometime last year, partly because I lacked a clear goal. I no longer wanted to live there or pass the NL1 proficiency test, which left me without a clear motivation.

After some reflection on this, and after watching Perfect Days, I came up with a goal (still very new, I’ll see if it sticks 😅): In 2026, work from Japan for a month to celebrate Hardcover’s 5-year anniversary. That’s still a year and a half away, which gives me a lot of time to learn and anticipate this. It also checks about 4 of my goals.

The goal of this would be:
+ Learn how to read Japanese at a basic level
+ Learn basic conversational Japanese, focusing on what would be needed to survive there for a month
+ Prepare to live in Japan for a month!

Right now my plan includes WaniKani (for learning kanji), Pimsleur’s Japanese course (for speaking) and Japanese the Manga Way (for grammar and structure).

If you have something that worked for you to learn Japanese, I’d love to hear about it!

Change to Maintenance Mode for Health and Fitness

In the last six months, I have focused a lot on my health. I tracked all of my calories (using LoseIt), went to the gym three times a week, and did cardio three times a week (usually Peloton or a run). I rarely had any alcohol. I minimized my desserts and didn’t eat out much. I targeted 1900 calories a day.

I lost 17 pounds (171 lbs → 154 lbs) while putting on 5 pounds of muscle (!).

At no time during this did it feel like I was depriving myself, but by the end it felt like I was spending too much time focused on tracking every calorie rather than just enjoying food.

I want to switch to a more relaxed approach to health while maintaining my current weight. This will mean less time focusing on the how and more time enjoying food and my current fitness level.

The goal of this would be:

– Stop tracking my foods
+ Continue with daily weigh-ins. Those will help verify if my exercise === calories in a similar way as tracking.
+ Switch from 6 exercise days a week down to 5.
+ Focus on getting 6k steps daily on weight training and Peloton days and 10k steps on all other days. (exceptions allowed if it’s rainy/snowy).
+ Whenever I go grocery shopping (about every other week), make a plan to get ingredients for a new recipe

Do a Weekly Review

I’ve written about weekly reviews before. I’ve tried weekly task organization too. This is a chance to check in with myself and see how I’m doing.

Lately, I’ve let these reviews swing entirely too much toward productivity and away from overall happiness. I want to switch more in that direction – using these as a chance to see if what I’m doing is making me happy or not.

The goal of this would be:

+ Conduct a weekly personal review. I do these in Notion in a folder for personal > reviews > 2024.
+ Focus on personal happiness and my relationship, not productivity.

Aggressively Say No

I was reading Slow Productivity by Cal Newport during my vacation and a number of things stuck with me. The TLDR of the book is this on page 8:

A philosphy for organizing knowledge work efforts in a sustainable and meaningful mannerm based on the following three principles:

  1. Do fewer things.
  2. Work at a natural pace.
  3. Obsess over quality.

My weekly review is a chance to verify I’m doing #2. I tend to obsess over speed more than quality while also taking on more than I often should.

The solution to this is to get better at saying no. That can mean saying no to working on a new Hardcover feature. Saying no to myself when I say, “I should build <insert new idea here>.” It can mean saying no when I say, “This barely works, but it’s good enough,” and instead write some damn tests (or, more likely, let Claude write them 😂).

The goal of this would be:

+ Be happy with whatever my output is – both in scope and depth
+ Create a sustainable pace for knowledge work

Focus on What You Can Change

The theme of all these is taking a step away from the news and distracting myself from *gestures broadly* everything.

I want to miss out on a constant barrage of destructive decisions by politicians, grifts to extract money, agencies gutted, courts packed, and everything else that will surely happen over the next 4 years.

Being able to tune this out daily and instead only look at the news occasionally is a privilege. I fully understand that. I still plan to support all the same politicians and politicians as before. I’ll be out holding signs at rallies protesting against whatever new right is being taken away. And who knows what else.

But what I won’t do is let myself drift into a doom-scrolling cycle that lasts a presidential term.

Make My 40s My Best Decade Every: Year 2 Update

2024-07-29 05:16:33

Two years ago when I turned 40 I set out some ambitious goals for the next 10 years.

The highlight was the line:

I want to make my 40s my best decade of my life (so far).

No pressure right. 😂

In the first 3 months of my 40s I tore my ACL, had surgery, had to let someone go from the Hardcover team and our 14-year old dog passed away.

It was a rough start.

Fortunately things have improved since then. I’ve tried to concentrate on not stressing myself out with additional pressure. I tend to put the most pressure on myself, and by it’s been amazing just dialing that down a little bit and noticing that I’m happier and less stressed.

I’ve also started drinking a lot less. Probably down from 8 drinks a week to more like 2-3. This was a result of two changes: not drinking at home and only having one drink when I’m out with friends or on a date with my wife.

By the time I’m 41…

Here are some of the goals I set out for my first year.

✅ I want to be able to hike the mountains of Utah (again)

After months of physical therapy after my ACL tear & surgery, I eventually recovered enough to hike again! In year 1 I didn’t hike all that much. One hike I did complete was Black Mountain – a 10 mile hike to the highest mountian we can view from our apartment window.

I attempted this same hike a few years ago in May, but there was too much ice in the scrambling part to complete it at that time. Doing it in July, on the 1-year anniversary of my ACL surgery, felt cathartic. Like I was finishing a book I’d left 95% completed.

✅ I want to get back to the point where I’m physically fit

“Fit” can mean a lot of things. My intention when I wrote this was that I wouldn’t want to use my knee as an excuse for not doing something. I’m not sure if I reached this in year one, but I’ve for sure reached it now. I’ve been skiing again, stood for hours at music festivals and concerts, run long distances (well, 10k 😅), and overall just haven’t worried about not being able to do something.:

❌ I want to grow Hardcover to pay for my food & housing

This one was always going to be a long shot. Hardcover did grow to over $1k in revenue per month, but our costs have grown too. We’re very close to breaking even. With over 1,600 users active each week, it’s a very lively place! We have some plans to increase revenue that we’re working on for this year.

By the time I’m 45…

I also set a few longer term goals.

🔜 I want to learn how to build mobile apps

Earlier this year I spent some time learning SwitftUI. Alongside a group of random people from Discord, we launched SpaceTube, YouTube for Spatial videos on the Apple Vision Pro. It was a fun, quick project.

However I wouldn’t say I learned how to build mobile apps as part of this.

I did learn that perhaps SwiftUI isn’t the path I want to go. Instead I’ve started learning React Native instead. I’m already comfortable with React, and it works on both Android and iOS. It’s likely we’ll move Hardcover to React Native someday – but I have a lot to learn first.

My hope right now is to switch Line of Thought from a web app to a mobile-only app using React Native and HealthKit. I have such a clear idea of the app I want to build – I just need to build it! 😅

❓ I want to go on a 6-week (or longer) international trip

This is a tricky one logistically. We’re planning to adopt a dog later this year. I wouldn’t want to leave our new family member alone, or with a stranger for that long a period of time. I’m unsure how this will work into actual plans.

We did spend two weeks in Korea in April 2024 which was amazing though! It reminded me how much I love being in a new city, eating new food and having new experiences every day.

Where would I/we go? I’m not sure. I’d love to spend more time in Japan. I could see many parts of Asia being amazing for an extended trip. I’ll keep thinking about this one for now.

Or maybe we’ll just decide to leave the US altogether based on the next election. 🤷

🔜 I want to grow Hardcover into a successful business

We’re making good progress on this. If Hardcover continues to grow 10x a year then I feel like this is only a matter of time. If our momentum slows down we may have to change course, but we’re not there yet.

For now it’s more about continuing to do what we’re doing! Listen to users and build what they want. Get the word out to more people. Find new people to work with. Repeat.

By the time I’m 50…

These were long-term when I set them. I have 8 years left. 😂

❓ I want to give away $1 million

This is dependent on Hardcover (or another business) generating revenue. There’s only so much money anyone needs, and it’s not as much as most people think.

🔜 I want to visit all 50 states by the time I’m 50!

This is only three trips away:

  • Take an Alaskan Cruise. We have a bunch of friends in Seattle that might be up for this one too.
  • Take a trip to Hawaii. With the fire and deluge of tourism lately, it feels like going there would be adding to the problem locals face rather than helping. I’d still like to go – and not stay in an Airbnb).
  • Take a road trip to the midwest. All the states in the US I haven’t been to are all grouped together (Wisconsin, Minnesota, Iowa, North Dakota, South Dakota, Nebraska). We have some friends that moved to the Chicago area it’d be fun to road trip out to.

❓ I want to figure out where to live long-term

Every year when our lease is up in our apartment we have the same discussions about where we should move. For the last year years we’ve been very happy here in SLC. The longer we stay here the more we love it!

To stay anywhere long-term we do like the idea of buying a house. What we could afford today would be a major step down from our apartment. That’s led us to be happy where we are.

If Hardcover ends up growing and providing some income, then I could see us having the ability to make a buying decision here. Until then, and until we know what direction our country is headed in, we’ll wait and see.

✅ I want to fitness to be on autopilot

I’m surprised to say I can actually check this one off already! Well, it’s not solved for good. Every plan needs to adapt to whatever life throws at it.

For now, my fitness plan includes:

  • Go to the gym Monday, Wednesday and Friday.
  • Peloton or run Tuesday, Thursday and Saturday.
  • Take Sundays off.

Fitness-wise I’m happy when where I’m at. I could walk a bit more, but that’s really it.

The hardest part was changing my morning schedule. Previous I’d sleep in as late as I wanted, then get up and have breakfast with my wife every day. In April I started workout out with an online personal trainer and waking up early for a morning workout 3x a week. Most days I end up waking up before my alarm and looking forward to going to the gym! It’s a chance to listen to audio books and wake myself up for the day.

What’s Changed?

30 Days From Learning to Launching a Swift App on Apple Vision Pro

2024-01-30 15:02:06

I have a confession to make: I’ve tried multiple times to learn iOS development and each time I’ve failed.

Let’s rewind to 2007. The very first iPhone was just released. When it initially came out, there was no App store or way to create apps. Apple’s workaround was simple: just build everything as a website (as long as there’s no Adobe Flash).

A year later in 2008 the App Store launched and developers could start creating apps using Objective-C.

I graduated college in 2005 and was working my first job making websites. In a few years I went from PHP to ColdFusion to ActionScript to Ruby on Rails. In each case I was building for the web – not for mobile.

When the App Store launched, I had to made a career decision: do I continue trying to learn how to build for the web and become really good at Ruby, do I try to switch to iOS development (from scratch), or try to do both.

I think many people have a point like this in their learning journey. They don’t learn something new until they need it. My jobs used web technology and I didn’t need to know iOS development.

There were a few times I tried to learn iOS development. I took the Stanford iOS course and learned some Objective-C basics. I read Head First iPhone and iPad Development and gained a better understanding of how components communicate. I took a course on iOS development at a local community college (and even made some friends). I worked on multiple Code School courses about Objective C and iOS development. I even went to WWDC and was even interviewed by a Brazilian newspaper with my coworkers Eric and Jon.

Throughout all of this I never dedicated the time needed to get good as iOS development.

Over the years I’ve set goals for myself to learn more about iOS development but each time I don’t dedicate enough time to make an impact. I’ve told myself that anything I create isn’t going to be as good as what seasoned developers can make. Or that a new solo dev can’t compete with people with a decade of expererience.

The sad part is if I’d continued learning a decade ago, that’d be me!

As part of my goal to make my 40s my best decade ever, I want to break out of this pattern and learn how to build apps using Swift. With the release of the Apple Vision Pro, I’m more excited about Swift development than I’ve ever been before.

I have no idea what the future holds for AR and VR, but in my gut I feel it’s a new medium that’s going to revolutionize the way we interact with computers – similar to how the iPhone did. I don’t imagine that’ll happen immediately, or even with the current iteration of AR/VR, but when it does I want to be able to build the apps that I dream about on it.

With that in mind, I’ve decided to keep a learning journal of my experience learning SwiftUI development with the goal of building apps for the Apple Vision Pro in 2024.

My goal is to ship an app on the Apple Vision Pro in February (!). Let’s go! 🙌

Day 1: January 28, 2024

Where to start! There’s no shortage of iOS development resources out there. Many educational resources start at the very beginning, which would be perfect for people wanting start from scratch.

I’ve never programmed in Swift before. Initially I thought, “OK, I’ll learn Swift first”. I watched a few Swiftful Thinking videos and quickly realized this is too basic for what I’m looking for. Swift as a language isn’t anywhere near as confusing as Objective-C.

Next step: let’s look for a course to start learning SwiftUI!

The two courses I found that looked the most promising are Design+Code and Kodeco. Kodeco was formerly raywenderlich.com, which has been a pillar in iOS education for a decade. Back at WWDC I even went to a party they threw!

Before jumping into a paid course, I decided to check out what the official Apple resources were for learning how to build apps. I was fortunate to stumble on the Sample App Tutorials, which were exactly what I was looking for!

Starting with the About Me app, these tutorials are amazing. You download a sample application that you can run locally. The website goes through the code file by file explaining the key parts and giving recommendations on some parts I can change to see how it impacts the app.

This was an ideal app to learn the basics. It’s a navigation bar, 4 static pages and some content that’s set in a single source of truth. Super straightforward and understandable from the code and description alone. This one showcases a bunch of concepts:

  • Navigation Tabs
  • Horizontal and Vertical stacks for organizing content
  • Text and Images
  • Looping over arrays
  • Scrollviews
  • Performing an action when a button is clicked
  • Various other styling options for corner radius, padding, fonts, aspect ratio and more.

A very solid start that already opens up a bunch of possibilities.

The next app they showcase is the Choose Your Own Story app. This one uses a NavigationStack to create a “choose your own adventure” story. You’re presented with a story and a number of choices for your next step. Clicking on one takes you to the next page by pushing a new view on the NavigationStack.

As a web developer, I’ve always wondered how some apps have a separate history for each tab in their navigation (like Letterboxd for example). Turns out the answer is that each tab likely has their own NavigationStack. That explains why clicking on a new tab clears the back button, and yet clicking back to a tab brings you to the last view you clicked on in that stack. 💁‍♂️

One thing I don’t fully understand is where an app starts. 🤔

Day 2: January 29, 2024

Before starting today I went back and started this blog post. I’ve found that when I write about what I’m learning I end up retaining much more of it. Might as well learn and share while I’m at it!

Before jumping to the next sample project, I wanted to figure out why the start file for the two projects was different. I noticed that the start files have a @main decorator and extend from App.

@main
struct AboutMeApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

On to the next project: Date Planner! This application is a nested todo app. You create a new Event with multiple todos associated with it. This app touches on a bunch of new concepts.

One concept I’ve interacted with a bunch in other apps is a List. A list contains rows components, each of which can be swiped left for additional actions (like delete). Recreating this kind of interaction in JavaScript would be a pain, yet in Swift it’s just this:

ForEach(eventData.sortedEvents(period: period)) { $event in
    NavigationLink {
        EventEditor(event: $event)
    } label: {
        EventRow(event: event)
    }
    .swipeActions {
        Button(role: .destructive) {
            eventData.delete(event)
        } label: {
            Label("Delete", systemImage: "trash")
        }
    }
}

These few lines do a lot! The EventRow is the component that shows up each row of the List. When the row is clicked, the EventEditor component is shown. And lastly you can swipe left to see the delete action. Here’s what that ends up looking like.

I learned a bunch from this app. The List, View and swipe controls are all concepts I’d love to implement on a native Hardcover App.

Day 3: January 30, 2024

To start, I realized I didn’t read everything about the Date Planner project. That made me realize that the view on the iPad was completely different than the iPhone app. Looking at the code to understand this I’m still a little fuzzy on how this is done, but it’s good to have an example of how it works.

The next app, Organizing with Grids, is simple in comparison with only two files (whew, I needed that after the 13 files from the last one). This one showcases a grid and updating the current state to change the title color based on what’s clicked. It’s simple, but it’s a good example of how grids work.

The grid from Organizing with Grids is hardcoded to be a single column. Editing Grids makes this concept dynamic with a Stepper.

One concept that I wish React.js had that was used in this demo used is the idea of an @binding variable:

@Binding var symbol: Symbol?

This allows a variable to be passed into a component, it to be reassigned in that component then for the calling context to get that updated value. So, a two-way binding.

Day 4: January 31, 2024

Day 6: February 2, 2024

It’s time: I picked up my Apple Vision Pro!

Ever since I watched the Hyper Reality video years ago, I’ve been excited about the possibilities offered by augmented reality.

Building an app for the AVP is one of my top motivations to work on this now.

I did the demo at the Apple store, which showcased some immersive videos and instructions on how to interact with the device. If you end up getting the device yourself, you can watch the same video from the AppleTV app, but the spatial video examples are only available through the demo.

Today we had some friends coming over for a party, and took the opportunity for everyone to go through a demo of their own. 😂

The results were a lot of people saying “wooooow”.

Day 7: February 3, 2024

Continued reading through more sample swift code from the Apple website. I think I’ve finished everything from the Sample Apps section that’s relevant to the type of apps I’m hoping to build.

Day 8: January 4, 2024

Through the AVP Subreddit I joined the Apple Vision Pro Discord. I found some recommendations on apps. One that I’d love to see is a way to share or find spatial videos. The ones in the demo were incredible, but I haven’t been able to find many other examples.

Day 9: February 5, 2024

I tried an experiment today of working on Hardcover using the Apple Vision Pro and posting about in realtime on Mastodon.

You can read the full thread if you’re curious. The takeaway was that everything was possible, but I was about 75% as productive and 100% more exhausted after 3 hours.

As far learning goes, I decided to switch from Apple’s sample code to videos with Kodeco. I watched the first course in the SwiftUI path, Your First iOS & SwiftUI App: An App from Scratch. It was a very gentle introduction without lingering on the basic syntax.

I ended up watching a bunch of these lessons from the AVP while my wife slept on my lap. 🤗

Day 10: February 6, 2024

Met up with a developer I found from the AVP Discord with the idea of building a YouTube for Spacial Videos.

I registered the spacial.tube and spacial.garden domains for this, but not sure if I’ll use either. For now I setup a Rails site on here from a template that’s a YouTube clone from a starter codebase.

Day 11: February 7, 2024

More developers are involved in the project now – we’re up to 6 in fact! Moved from space.tube to spacetube.app, as a Next.js app landing page.

Day 12: February 8, 2024

Had the kickoff meeting for the group of us building SpaceTube. We’re aiming to launch something by early March 2024.

I’ll be mostly working on the backend, but this’ll be a great chance to understand how the SwiftUI side works as it’s built out by some developers with a lot more experience than my 11 days. 😅

From a technical standpoint, the app will be a SwiftUI app for the Apple Vision Pro, using Supabase for the database, and Next.js for the few backend actions and a landing page. I initially put it in Rails, but this tech stack means less code overall – and less that any one person has to support.

There’s a Swift library for Supabase that’ll allow us to read and write directly from it.

Day 13: February 9, 2024

Someone joined the Hardcover Discord interested in creating an iOS app. We’re going to work together and build something while we’re learning. 🙌

They shared two in depth articles about Swift design that I was able to understand about 40% of.

Day 14: February 10, 2024

Spent most of today working on non-iOS stuff: SpaceTube newsletter setup and and updating this blog post.