JAMES LONG

All Posts

How one word in PostgreSQL unlocked a 9x performance improvement

May 26, 2020
At the very heart of Actual is a custom syncing engine. I'd like to talk about a PostgreSQL feature that enabled a 9-10x performance improvement.

A case study of complex table design

May 6, 2020
This is a look at how I approach product design and all the considerations you need to think about. I explain some improvements in the recent version of Actual's budget table.

Joining Stripe

April 6, 2020
I'm joining Stripe.

The wonderful sound of an atomic commit

February 11, 2020
Atomic commits are one of the most important properties of reliable software. Recently I improved the syncing layer of Actual using transactions, and I talk about why it's so important.

Thinking about growth and profit

January 9, 2020
A deep dive into the relationship between growth and profit after my last post about profit forecasting.

Analyzing churn rates, free trials, and other metrics

January 7, 2020
I sit down and learn how to get insights from churn rates, conversion rates, and more to answer some important questions about my product.

A Review of Actual in 2019

January 2, 2020
A look back on Actual's progress in 2019.

The Secret of Good Electron Apps

June 25, 2019
Some people really hate Electron apps. They eat up memory, boot slowly, and aren't very responsive. What if I told you there's a secret that automatically minimizes these problems? They key is doing the bulk of your work locally in a background process, and doing so has some fantastic development benefits.

I'm Bringing My Blog Back

June 10, 2019
The last couple of years I've been building Actual. It's taken a lot out of me. Building, marketing, and trying to bootstrap a product yourself is ridiculously hard. I'm bringing my blog back to write about the path to profitability.

Why I'm Building Actual

November 28, 2017
Over the last year I've been quietly building Actual, a personal budgeting tool. It's a free local app that will sync across all devices. I'm building it because I wanted a tool that is flexible and simple, with a solid budgeting system.

Opening Up My Development Process

July 18, 2017
Livestreaming has always been popular in certain communities like gaming, but recently it's been getting popular with programmers. ... I plan on livestreaming while I work on a product every week.

Releasing Prettier 1.0

April 13, 2017
We officially announced prettier over two months ago as a way to solve the problem of wasting time formatting your code. It started as an experiment but it clearly resonated with a lot of people, amassing ~7000 GitHub stars and over 100,000 monthly npm downloads in just two months. Now it's time for 1.0.

How I Became a Better Programmer

March 20, 2017
Several people at React Conf asked me for advice on becoming a better programmer. For some reason, people see me as a pretty advanced programmer worth listening to. I thought it would be worthwhile to write down my "mental model" for how I have approached programming over the years.

Talking Open Source on Changelog

March 9, 2017
Changelog invited me to talk about open source and you can listen to it here.

Why I'm Frequently Absent from Open Source

February 26, 2017
Sarah and I have been married for 6 years as of today (with 2 kids, Evy and Georgia). I write about a lot about technology on my blog but I don't write about the thing that I spend more time on and is way more important than tech: my family. I thought our 6-year anniversary is a good time to acknowledge that!

A Prettier JavaScript Formatter

January 10, 2017
Today I am announcing prettier, a JavaScript formatter inspired by refmt with advanced support for language features from ES2017, JSX, and Flow.

Leaving Mozilla

December 13, 2016
Last week I was in Hawaii for a Mozilla work week. I saw many great friends, but I also kept faintly recognizing people without remembering how I knew them. Sometimes I even thought I knew them from other parts of my life. It made me realize just how much Mozilla has become part of my life.

Exploring Continuations: Resumable Exceptions

June 8, 2016
Today we're going to implement resumable exceptions. Common Lisp is known for this feature. Few other languages implement them, but I found an implementation for OCaml by (unsurprisingly) Kiselyov.

Implementing a Stepping Debugger in JavaScript

May 26, 2016
In my previous post I introduced Unwinder, a project which implements continuations (and stepping debuggers) in JavaScript. In this article I explain how the compiler is implemented.

What’s in a Continuation

May 17, 2016
Many people have heard the word “continuation” because it has something to do with node’s callback hell. I don’t think most people understand what continuations really are, though. They aren’t just a callback function used by async functions.

Two Weird Tricks with Redux

April 13, 2016
I have now used Redux pretty extensively in multiple projects by now, especially the Firefox Developer Tools. While I think it breaks down in a few specific scenarios, generally I think it holds up well in complex apps. Certainly nothing is perfect, and the good news is when you want to do something outside of the normal workflow, it’s not hard.

RIP Over-Engineered Blog

April 1, 2016
It’s been 6 months since my last blog rewrite, so it’s time for another one. This time, let’s subtract.

Moving Breakpoints Intelligently

February 26, 2016
In most debuggers, a breakpoint will "slide" if the clicked line doesn't have any code. This is supposed to be a helpful feature, but it becomes **infuriating** if it behaves wrongly. In Firefox 46, we made our breakpoint sliding algorithm much more robust.

On the Road to Better Sourcemaps in the Firefox Developer Tools

January 11, 2016
In this post, I explain why it has taken so long to get the Firefox console sourcemapped. It requires an unobtrusive debug mode which is really hard to do, but we got it working. The console now has access to sourcemaps, so we are only one small step away from getting it working.

Starters and Maintainers

December 29, 2015
"It’s late Friday night, my wife is already asleep, and I finally found time to go through those pull requests on that old project I put up on github last year. My daughter is getting up at 7:30 though, so I better not stay up too late. ..."

A Simple Way to Route with Redux

November 25, 2015
It's not clear how to use redux and react-router together on a project, but there's actually a pretty simple way to do it. Introducing redux-simple-router, a way to keep the current URL in sync in your app state and router instance.

My ReactiveConf Talk

November 10, 2015
Last week I gave a talk at ReactiveConf about how React and Redux solve a lot of issues in complex apps. I talked about how vital it is to keep things as simple as possible, and how we're trying to clean up the code of Firefox Developer Tools. Watch it here.

Immutable Data Structures and JavaScript

October 1, 2015
A little while ago I briefly talked about my latest blog rewrite and promised to go more in-depth on specific things I learned. Today I'm going to discuss various ways to use immutable data structures in JavaScript.

The Seasonal Blog Redux

September 17, 2015
It's that time of year again! The weeds are growing, the air is thick and stagnant, and I just deployed another refactoring of my blog. "Why does he keep working on his blog," you're thinking, "when I could do all of that with a static-site generator like Jekyll?"

Why React Native is Different

May 6, 2015
I gave a talk at a local JavaScript meetup in Richmond, VA about React Native. Here are my slides and a recording of the talk. Check this out if you want to see why React Native is so cool!

Stop Trying to Catch Me

April 7, 2015
I'm probably going to regret this, but this post is about promises. There are a few details that I'd like to spell out so I can point people to this post instead of repeating myself. Here are a few reasons why I don't like promises.

Live Editing JavaScript with Webpack (Part III)

April 2, 2015
Part I and Part II of this series lay the groundwork for building not only the frontend code of your app, but also the backend. So far, while the system has a nice consistency, it offers little to the casual observer. Today, in this final post, we are going to look at how to live update a running JavaScript system using webpack's hot module replacement.

Backend Apps with Webpack: Driving with Gulp (Part II)

March 19, 2015
In Part I of this series, we configured webpack for building backend apps. Now we will look at how to manage frontend and backend code at the same time, and integrating our system with nodemon to restart the server on changes.

Backend Apps with Webpack (Part I)

March 16, 2015
Webpack is an amazing tool. This is the first post in a series about how to use it for backend apps as well as frontend. Using the exact same build process for both is amazing.

Impasse

March 11, 2015
I put a lot of pressure on myself to be productive. I love to both learn and obsess about interesting ideas, but also turn them into actual productive things in real life. It's exhausting sometimes. There usually isn't enough time to do both.

Radical Statements about the Mobile Web

February 20, 2015
I've been thinking a lot about what the web needs to compete with high-end native mobile apps. This is a list of bold statements that I think warrant discussion for getting the web to perform well on mobile.

First Impressions using React Native

February 6, 2015
React Native is a new way to build native apps, using all the same technology you learned with React.js. It's amazing. In this article I give a demo of my first app built with it and explain the experience.

Presenting The Most Over-Engineered Blog Ever

January 15, 2015
Several months ago <a href="https://jlongster.com/Blog-Rebuild--A-Fresh-Start">I posted</a> about plans to rebuild this blog. After a few false starts, I finally finished and launched the new version two weeks ago. The new version uses React and is way better (and I <a href="https://github.com/jlongster/blog">open-sourced it</a>).

Modularity

January 8, 2015
Recently there's been some heated discussion over writing modular code, what that means, and which style is better. In this article I reflect on the discussion and about respecting each other.

My 2014 Retrospective

January 3, 2015
I don't usually do these end-of-year posts, but I'm trying to write more so it seems like a good opportunity. It's also nice to verbalize where I'm at with general goals. I put a lot of pressure on myself to make progress on my goals, so it's good to take a step back and see what happened.

Transducers.js Round 2 with Benchmarks

October 12, 2014
Over the past week I've been hard at work polishing and benchmarking my transducers library. I just published a new version with benchmarks so let's take a look at the new features and performance.

Transducers.js: A JavaScript Library for Transformation of Data

September 18, 2014
In this post we study transducers, a new technique from Clojure, for generalizing how we transform data. I have implemented them in JavaScript and released <a href="https://github.com/jlongster/transducers.js">transducers.js</a>, which will radically simplify how you deal with data transformation across all data types.

Taming the Asynchronous Beast with CSP Channels in JavaScript

September 8, 2014
Every piece of software deals with complex control flow mechanisms like callbacks, promises, events, and streams. It turns out using CSP which leverages channels for asynchronous communication vastly reduces the complexity of everything. This has drastic effects not only on server-side code, but also on user interfaces.

Blog Rebuild: Build Systems & Cross-Compiling

August 14, 2014
To begin rebuilding my blog, I need a way to cross-compile JavaScript and have modules work in the browser. In this article, I describe all the research I did into build systems and what I ended up with.

Blog Rebuild: A Fresh Start

July 30, 2014
I wrote my own blogging engine for jlongster.com two years ago, and it has served me well. The code is old and the cracks are showing, however, so I'm going to rewrite it completely with new web technologies and blog throughout development.

Compiling JSX with Sweet.js using Readtables

July 2, 2014
<a href="http://facebook.github.io/react/docs/jsx-in-depth.html">JSX</a> is a Facebook project that embeds an XML-like language in JavaScript, and is typically used with <a href="http://facebook.github.io/react/">React</a>. Many people love it and find it highly useful. Unfortunately it requires its own compiler and doesn't mix with other language extensions. I have implemented a <a href="https://github.com/jlongster/jsx-reader">JSX "compiler"</a> with <a href="http://sweetjs.org/">sweet.js</a> macros, so you can use it alongside any other language extensions implemented as macros.

Removing User Interface Complexity, or Why React is Awesome

May 13, 2014
I've been studying frameworks and libraries like Ember, Angular, and React the past several months, and given Web Components a lot of thought. I found React to be the most enlightening, and I'll explain why.

Moving to the Developer Tools Team

March 18, 2014
After 3 years at Mozilla, this week I'm joining the Firefox Developer Tools team. This will be a great fit for me, and I'm really excited to work with them and make our performance and debugger tools rock.

Sweet.js Tutorial #2: Recursive Macros and Custom Pattern Classes

March 12, 2014
This tutorial explores how to write more complex sweet.js macros. There are several use cases which require more control over pattern matching, and recursive macros and pattern classes allow this and let you build abstractions when writing macros.

Open-Sourcing My Gambit Scheme iOS Game from 2010

March 8, 2014
Back in 2009-2010, I got Gambit Scheme running on iOS and decided to build a game with it. The result was Farmaggedon, a stupid game where you blow up farm animals to avoid being hit by them.

Writing Your First Sweet.js Macro

February 6, 2014
This is the first entry in a series about writing JavaScript macros with <a href="http://sweetjs.org/">sweet.js</a>. You will learn how to write your first macro, basics of pattern matching, and how to run the sweet.js compiler and use sourcemaps for debugging.

Stop Writing JavaScript Compilers! Make Macros Instead

January 7, 2014
JavaScript is everywhere, but that's a double-edged sword. It's hard for everyone involved to agree on how the language should move forward, let alone implement changes in all implementations. Some people write compilers to implement extensions, but that's bad. sweet.js is a new project that implements macros for JavaScript, and it's much better way to implement language extensions.

A Deep Dive into Asynchronous Templating

December 4, 2013
I wrote a JavaScript engine called Nunjucks, and it recently reached 1.0. One the new features is asynchronous templating, which lets you use async APIs inside custom filters and extensions. I'll show you how I implemented it, allowing templates to be paused when rendering and resumed later.

The Story of My Desk

October 17, 2013
I've been searching for the perfect desk for the past few years. My desk needs to be sturdy, beautiful, and just the right size. After several attempts to solve this problem, I decided just to build my own. This is that story.

A Closer Look at Generators Without Promises

June 7, 2013
In my last post, I studied how combining promises and generators provides a nice solution for callback hell. Here I look at a few solutions for simply using generators, without promises at all, in node to write nice async code.

A Study on Solving Callbacks with JavaScript Generators

June 5, 2013
Callback hell is a real problem in node.js. Since generators have landed in V8, I take a look at how we can write code with them, leveraging promises to handle the details. This technique vastly improves code with asynchronous workflows.

My JSConf 2013 Diary

May 29, 2013
While at JSConf 2013 I'm taking notes for each talk and taking pictures so that I don't miss anything. Check this out if you are interested in what's going on at JSConf.

Compiling LLJS to asm.js

March 25, 2013
Mozilla recently announced asm.js, a specification of a restricted subset of javascript that can be ridiculously optimized. It's difficult to write by hand, so I ported a language called LLJS to compile to it, unlocking high performance in browsers with a C-like language.

Making Sprite-based Games with Canvas

March 19, 2013
This article explores the process of creating a sprite-based game for the web using canvas. It provides an in-depth explanation of sprite animations, collisions, and much more.

Reflections on My Game Off Experience

December 10, 2012
After an intense few weeks building a multiplayer first person shooter on the web, I take a look at what I achieved and what I did wrong.

Making Web Games #5: Authoritative Server

November 26, 2012
Now that I have a multiplayer server working for my WebGL FPS, I improve it to become an "authoritative server". It runs client-side prediction and interpolation to keep gameplay smooth but reject any cheating.

Making Web Games #4: Multiplayer Networking

November 23, 2012
First person shooters aren't very fun unless you can play with other people. In this article I show how I implemented a basic multiplayer server for my game.

Making Web Games #3: 3d Engine

November 15, 2012

Game Off Update #1: Graphics

November 8, 2012

Why sweet.js Matters

October 26, 2012

The Quest for Javascript CPS: Part 2

May 18, 2012
I successfuly compiled a Lisp to Javascript in Continuation Passing Style (CPS) with an acceptable performance hit, and was able to write a stepping debugger and a solution for callback hell.

Compiling to Javascript in CPS, Can We Optimize?

May 11, 2012
I implemented CPS in Outlet and benchmarked the result, as seen here. It's very slow, but is there a way to optimize it?

Tilt This

April 3, 2012

New whizz-bang in Outlet

February 16, 2012

Outlet gets a Personality

January 16, 2012

Outlet gets Macros

January 13, 2012

Flame: My 2d Game Experiment

December 30, 2011

SICP 2.6: Church Numerals

December 26, 2011

SICP 2.5

December 14, 2011

SICP 1.35

December 13, 2011

Going Fullscreen with Canvas

November 21, 2011