Blog Posts

Building ftextarea: A Vanilla Rust + WebAssembly Textarea App

I wanted a simple textarea where I could paste links and jot down quick notes. No login, no cloud sync, no fancy formatting — just a textarea that saves to localStorage. Most existing tools are overkill for this use case.

So I built ftextarea — and used it as an excuse to learn Rust + WebAssembly without frameworks.

Try the live app →

View the source code →

The Goal

Build a static web page with:

My 2026 New Year's Resolutions

Here’s what I’m aiming for in 2026: health and fitness, coding, learning, and writing.

This list focuses on side projects and learning goals, I’m keeping personal and work-related resolutions private.

Each goal below includes a measurable target, the bigger picture behind it, and why it matters to me.

I’ll update this post throughout the year with progress notes under each goal. Check back to see how it’s going.

Health & Fitness

Stay in ketosis for 30 days straight

I’ve read great things about keto for general health and weight management. I want to experience what ketosis actually feels like and figure out what it takes to get there. The 30-day target forces me to find a sustainable approach: simple recipes that work with a full-time job and a family at home.

Getting Started with Rust Async

⚠️ PLACEHOLDER CONTENT: This is a fake blog post with dummy content for demonstration purposes only.

Introduction

Rust’s async/await syntax makes writing asynchronous code feel almost synchronous. Here’s a quick look at how it works.

Basic Example

use tokio::time::{sleep, Duration};

async fn fetch_data(id: u32) -> String {
    // Simulate network delay
    sleep(Duration::from_millis(100)).await;
    format!("Data for item {}", id)
}

#[tokio::main]
async fn main() {
    let result = fetch_data(42).await;
    println!("{}", result);
}

Spawning Concurrent Tasks

You can run multiple futures concurrently with tokio::join!:

Flutter State Management Tips

⚠️ PLACEHOLDER CONTENT: This is a fake blog post with dummy content for demonstration purposes only.

The Problem

Managing state in Flutter can get messy. Here are some patterns that help.

Using ValueNotifier

A simple approach for local state:

class CounterWidget extends StatefulWidget {
  const CounterWidget({super.key});

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  final _counter = ValueNotifier<int>(0);

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<int>(
      valueListenable: _counter,
      builder: (context, value, child) {
        return Text('Count: $value');
      },
    );
  }

  void increment() => _counter.value++;
}

Extension Methods

Dart extension methods can clean up your code:

Rust Error Handling Patterns

⚠️ PLACEHOLDER CONTENT: This is a fake blog post with dummy content for demonstration purposes only.

The ? Operator

Rust’s ? operator makes error propagation elegant:

use std::fs::File;
use std::io::{self, Read};

fn read_config() -> io::Result<String> {
    let mut file = File::open("config.toml")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

Custom Error Types

Define your own errors with thiserror:

use thiserror::Error;

#[derive(Error, Debug)]
pub enum AppError {
    #[error("Configuration file not found")]
    ConfigNotFound,
    
    #[error("Invalid data: {0}")]
    InvalidData(String),
    
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
}

fn load_config() -> Result<Config, AppError> {
    let data = std::fs::read_to_string("config.toml")
        .map_err(|_| AppError::ConfigNotFound)?;
    
    parse_config(&data)
        .ok_or_else(|| AppError::InvalidData("malformed TOML".into()))
}

The anyhow Crate

For applications (not libraries), anyhow simplifies everything: