<feed xmlns="http://www.w3.org/2005/Atom">
  <title>
  <![CDATA[ DCHENO.WORK ]]>
  </title>
  <link href="https://dcheno.work/atom.xml" rel="self"/>
  <link href="https://dcheno.work/"/>
  <updated>2026-02-02T00:00:00+00:00</updated>
  <id>https://dcheno.work/</id>
  <entry>
    <title type="html"><![CDATA[ Building A Bike ]]></title>
    <link href="https://dcheno.work/building-a-bike/"/>
    <author><name>dcheno</name></author>
    <updated>2026-02-03T00:00:00Z</updated>
    <id>https://dcheno.work/building-a-bike.html</id>
    <content type="html"><![CDATA[ <figure>
<img src="https://dcheno.work/images/labeled-bike-parts.png" alt="A diagram of a bike with the parts labeled by number" />
<figcaption aria-hidden="true">A diagram of a bike with the parts labeled by number</figcaption>
</figure>
<p>Some time last year I took my 800th Citibike ride.</p>
<p>I&#x2019;ve long been a proponent of the annual pass. It&#x2019;s a fraction of the cost of a transit pass for the same period of time, and it&#x2019;s a great complement to the MTA system. You have a marginally free last mile option at most subway stops. You can ride a bike one way and train back if it&#x2019;s raining. If a bike is broken you just dock it and grab another.</p>
<p>I&#x2019;ve even told myself that dragging a 40 pound CitiBike up and over the Manhattan bridge is just bonus exercise.</p>
<p>But secretly I&#x2019;ve always coveted a bike.</p>
<p>CitiBikes are almost always rideable, but too often you miss out on that delightful coasting feeling a well cared for bike can provide. I&#x2019;ve also always liked the idea (if not the reality) of self maintenance and customization.</p>
<p>So when our new apartment came with a bike-sized Harry Potter closet<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>, I immediately started thinking about putting together a bike.</p>
<p>As I&#x2019;ve been told, bikes are available to purchase whole and in working order. But I wanted to know how to put everything together myself.</p>
<p>There&#x2019;s plenty of good information on bike assembly online, but I found myself wishing more people had shared their own process. So this is me sharing a bit of my process.</p>
<p><strong>It&#x2019;s important to note that I&#x2019;m not a bike mechanic. I&#x2019;m sure I&#x2019;ll say a few things here that are wrong. I&#x2019;d suggest having a professional or at least someone experienced with bikes, check your work.</strong> But I hope it&#x2019;s helpful for anyone else who is trying to get into building their own bike.</p>
<h2 id="sourcing">Sourcing</h2>
<p>Collecting all the components ended up being the hardest part of the project.</p>
<p>Something I wanted but couldn&#x2019;t couldn&#x2019;t quite find was a collated list of all the individual parts I would need.<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a></p>
<p>Here&#x2019;s what I ended up buying:</p>
<table>
<thead>
<tr>
<th style="text-align: left;">Part</th>
<th style="text-align: left;">Shimano ID</th>
<th style="text-align: left;">Source</th>
<th style="text-align: center;">New?</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">Frame (w/ fork)</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Seatpost</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Stem</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Bike Jumble</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Brake/Shift Levers</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Bike Jumble</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Handlebars</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Bike Jumble</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Seat</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Bike Jumble</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Crankset (with arms)</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Craigslist</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Bottom Bracket</td>
<td style="text-align: left;">SM&#x2011;BB6700</td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Cassette (with Chain)</td>
<td style="text-align: left;">CS/CN-6600</td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Front Derailleur</td>
<td style="text-align: left;">FD-5600</td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Rear Derailleur</td>
<td style="text-align: left;">RD-6600</td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Brake Calipers</td>
<td style="text-align: left;">BR-6600</td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Wheelset</td>
<td style="text-align: left;">WH-RS31</td>
<td style="text-align: left;">Ebay</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Cable Stops<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Bike Shop</td>
<td style="text-align: center;">New</td>
</tr>
<tr>
<td style="text-align: left;">Pedals</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Bike Shop</td>
<td style="text-align: center;">Used</td>
</tr>
<tr>
<td style="text-align: left;">Tires</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">performancebike.com</td>
<td style="text-align: center;">New</td>
</tr>
<tr>
<td style="text-align: left;">Inner tubes</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">performancebike.com</td>
<td style="text-align: center;">New</td>
</tr>
<tr>
<td style="text-align: left;">Brake Cables</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">Bike Shop</td>
<td style="text-align: center;">New</td>
</tr>
<tr>
<td style="text-align: left;">Shifter Cables</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">performancebike.com</td>
<td style="text-align: center;">New</td>
</tr>
<tr>
<td style="text-align: left;">Front Derailleur Shim</td>
<td style="text-align: left;"></td>
<td style="text-align: left;">performancebike.com</td>
<td style="text-align: center;">New</td>
</tr>
</tbody>
</table>
<p>A warning from someone who now has experience: don&#x2019;t do this for cost savings. Putting together your own bike isn&#x2019;t going to save you any money. You can find a better deal for a whole bike on Craigslist.</p>
<p>Shipping added up to quite a bit on its own. I wish I had been able to buy more locally, but I wasn&#x2019;t confident in my ability to determine compatibility for random parts. I stuck to parts I had vetted, which were easier to find online.</p>
<p>I started by looking up bike sizing guides online. For my height, most places suggested a 53 to 54 cm frame.</p>
<p>Back when I was in school and student-level broke, I bought an undersized powder blue Schwinn off of Craigslist. I had to ride with the seat post maxed out, and once, while I was biking down Buffalo Speedway, it came out of the frame. Luckily I caught it between my thighs, but this time I was excited to get a properly sized bike.</p>
<p>I found a frame I liked on Ebay. I also bought a seatpost from the seller and they threw that into the same box.</p>
<p>When the frame arrived, I took a rag and magic eraser to it until it was nice and shiny. Then I got stuck.</p>
<p>I had no idea which part to buy next. And beyond that, I had no idea how I would tell which models of parts would work together. I mentioned to one of my cyclist friends that I was looking for bike parts, and he suggested <a href="https://www.nybikejumble.com/">the New York Bike Jumble</a>, a giant cycling-oriented flea market that takes place in Park Slope twice a year. It happens to be 2 blocks from our apartment.</p>
<p>So I waited for the Jumble. I still didn&#x2019;t know how to gauge part compatibility, but I figured I had waited long enough. I just wanted to buy something.</p>
<p>The Jumble has a fun holiday atmosphere. I bought a set of brake/shifter levers from a pile of parts on a collapsible table. The guy selling them asked me what I wanted to pay for them. I told him I had no idea.</p>
<p>The shifters were Shimano (Shimano dominates the bike parts market) with a model number of ST-5600. This meant nothing to me, but it gave me something to Google.</p>
<p>My shifters were part of the &#x201C;105&#x201D; line of parts from the late 00&#x2019;s. Shimano offers a number of product lines for road bikes. In descending order of quality (and price), the main ones are Dura-Ace, Ultegra, 105, and Tiagra.</p>
<p>Most importantly, I found out that Shimano offers an archive of compatibility guides on their website.</p>
<p><a href="https://productinfo.shimano.com/en/archive">https://productinfo.shimano.com/en/archive</a></p>
<p>This is the one I ended up using:</p>
<p><a href="https://productinfo.shimano.com/pdfs/product/archive/2011_Compatibility_en.pdf">https://productinfo.shimano.com/pdfs/product/archive/2011_Compatibility_en.pdf</a></p>
<p>I&#x2019;ve since learned that compatibility for most parts isn&#x2019;t so strict. But having these guides gave me more purchasing confidence.</p>
<p>The Ebay seller I bought my frame from also included the relevant measurements for it in the posting. Things like wheel size, head tube diameter, etc. I found myself referencing this quite a bit. If that hadn&#x2019;t been available I would have needed to pick up a measurement caliper. Maybe I should have anyway.</p>
<p>I spent the next couple of months picking up parts on Ebay and Craigslist.</p>
<h2 id="assembling">Assembling</h2>
<p>Going into this project I thought part of the fun would be getting a bunch of cool bike tools. Turns out bike tools are expensive. Fortunately I didn&#x2019;t actually end up needing many of them.</p>
<p>Here&#x2019;s what I did ended up using:</p>
<table>
<colgroup>
<col style="width: 10%" />
<col style="width: 89%" />
</colgroup>
<thead>
<tr>
<th style="text-align: left;">Tool</th>
<th style="text-align: left;">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;"><strong>Hex keys</strong></td>
<td style="text-align: left;">They sell fancy ones online, but I was able to get away with using the standard set I had on hand. My understanding is that if you have fancy carbon fiber components you should use a torque wrench.</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Cable cutters</strong></td>
<td style="text-align: left;">I got <a href="https://www.performancebike.com/birzman-cable-cutter-bm11-st-cc02-k/p436863">these ones</a>. I thought they had a cable crimper, but I seem to be wrong. I&#x2019;d suggest paying up to get one with a crimper.</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Pliers</strong></td>
<td style="text-align: left;">Since my cable cutters didn&#x2019;t have a crimper, I used the corner of a pair of pliers to crimp them. It&#x2019;s not pretty but does the trick. I used a standard set of pliers I had lying around.</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Bottom Bracket tool</strong></td>
<td style="text-align: left;">I borrowed this from a friend. You shouldn&#x2019;t need one often.</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Chain tool</strong></td>
<td style="text-align: left;">I had an old one lying around.</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Tire Levers</strong></td>
<td style="text-align: left;">People on the internet say you don&#x2019;t need these. I did manage to get a tire on and off once without them but my thumbs haven&#x2019;t felt the same since.</td>
</tr>
</tbody>
</table>
<p>There are great guides on the internet on how to do every part of a bike build. I&#x2019;m not going to do a better job than the mechanics who wrote those so I&#x2019;ll focus here on things I found tricky or tips I found particularly useful.</p>
<p>The first thing I learned was to put bike lube basically everywhere. Almost every installation guide starts with &#x201C;spread lubricant over the threads of X&#x201D;. You can buy a tube of bike grease at any bicycle store.</p>
<p>Getting to smell like you do real work with your hands is a little added bonus of doing your own maintenance.</p>
<h3 id="bottom-bracket">Bottom Bracket</h3>
<p>The bottom bracket is the bearing system for your crankset. There are two main types: internal and external. This refers to where the actual ball bearings sit. The difference is visible in how they sit in the bike. An external bearing will have more than just the spindle protruding out from the frame.</p>
<p>The compatibility with the frame depends on the diameter, width, and thread direction of the bracket. My understanding is that this has mostly standardized these days, but probably good to check.</p>
<p>You also need to make sure the bracket is compatible with your crankset. This is where the external vs.&#xA0;internal comes into play as well.</p>
<p>I was able to get my bracket most of the way into the frame by hand. If I had gotten creative with rubber bands and grips I might have been able to get it further, but I was able to borrow a bottom bracket tool from a friend and that made it much easier.</p>
<p>Annoyingly, there can also be compatibility issues between bracket tools and brackets.</p>
<p>I don&#x2019;t anticipate having to take the bracket on and off much, so I put off buying the tool myself.</p>
<p>Once I had the bottom bracket on the bike, installing the crankset (spindle, chainrings, and pedal cranks), was straightforward.</p>
<h3 id="cassette">Cassette</h3>
<p>There&#x2019;s a tool you can use to tighten the lock ring of the cassette. I don&#x2019;t have that tool, so I did this by hand. I&#x2019;d like to get it tightened soon.</p>
<p>I read that depending on the number of gears and the rear tire width, you might need spacers to properly fit the cassette. I have a 10-speed cassette and an 11-speed wheel, so I was worried about this, but my cassette came with a spacer.</p>
<h3 id="chain">Chain</h3>
<p>I always forget that you have to break the chain to install it. Breaking it with a chain tool isn&#x2019;t difficult, but you do have to have a way of getting it back together.</p>
<p>I bought a quick-release link for a few dollars from a local bike store. There are special tools for opening and closing the quick release link, but I followed some advice online where I used the tension created by holding the rear brake and stepping down on the pedal to pop the link closed. I found this more difficult than advertised, so I would consider buying one of the tools for the next time I have to do this.</p>
<p>You&#x2019;ll find plenty of advice online on how to size a chain. It&#x2019;s definitely easiest if you can compare to the chain you are replacing, but I wasn&#x2019;t replacing another chain.</p>
<p>My friend&#x2019;s advice was to put the chain around the biggest front and rear gears and then go 2 rivets further. Turns out my chain was one link short for this. Maybe that&#x2019;s why I have a hard time shifting into my largest rear gear.</p>
<h3 id="brakes">Brakes</h3>
<p>The brake cables I bought had studs on both ends of them. One was pear shaped. The other looked like a little drum. Turns out road bikes typically use the pear-shaped cable end and mountain bikes usually take the drum-shaped one.</p>
<p>You cut off the end you don&#x2019;t need and thread the wire in from that direction.</p>
<h3 id="barrel-adjusters">Barrel Adjusters</h3>
<p>The best piece of advice I have for fine tuning the brake and shifter tension is to make use of the barrel adjusters.</p>
<p>The barrel adjusters are little knobs that sit around the cables near the brake calipers and rear derailleur. You can spin them to loosen or tighten tension.</p>
<p>I had an easier time of things once I realized that you could start with the barrel adjusters loose, get your brake or derailleur in a reasonable, if a bit loose, position, then tighten the adjusters.</p>
<h3 id="cutting-and-capping-cables">Cutting and Capping Cables</h3>
<p>I was overly cautious when cutting my cables on my brakes and derailleurs the first time. I wanted to make sure I had some extra cable in case I had gotten the measurement wrong.</p>
<p>I left my rear derailleur cable too long and it got caught on something during my first ride (probably the derailleur). This ripped the cap off and frayed the cable.</p>
<p>I was able to cut the cable again and recap. While I think it&#x2019;s still a good idea to leave a little extra cable, make sure it&#x2019;s not long enough to get caught in anything.</p>
<p>My other piece of advice is to be careful when cutting cables, especially frayed ones. It&#x2019;s easy for the cable filaments to spring apart and scatter over the floor.</p>
<p>This happened when I was trimming the end of one of my cables in our apartment. I thought I had found all the pieces, but I woke up a week later with a bit of cable filament sticking out of my big toe.</p>
<h3 id="cleaning-the-shifters">Cleaning the Shifters</h3>
<p>When I bought it, my right shifter had a gummy feeling in its action. I had to press it very precisely to get it to shift up.</p>
<p>I found a video on <a href="https://www.youtube.com/watch?v=yzLxyrVQ_00">Youtube on how to clean out a shifter</a>. Basically you blast it out with WD-40 and then some special shifting spray. I didn&#x2019;t have any of the shifting spray, so I just did the WD-40 part. It was messy, but it fixed the shifter almost immediately.</p>
<h2 id="riding">Riding</h2>
<p>The first pair of pedals I bought weren&#x2019;t great for city riding. They had toe cages that required getting your feet in and out of the pedal in a specific way.</p>
<p>I tried it out twice around the park. The pedals were workable, but using them still required thought, and I don&#x2019;t want to be thinking about toe position when I&#x2019;m stopping and starting at stoplights.</p>
<p>So I rode down to the used bike parts store this past Saturday to grab a pair of flat pedals<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a>. It was my first time riding the bike since properly inflating the tires, and I was enjoying that avian thrill you get from the coasting power of a road bike.</p>
<p>It was snowing lightly on my way out, but it wasn&#x2019;t accumulating. I found a pair of workable pedals and a cheap bell for my handlebars. As I was checking-out, I caught a glimpse out of the windows at the back of the store: the falling snow had erased the sky.</p>
<p>There was already a quarter inch of slush on the roads. I took the ride back very cautiously. I wiped down the bike when I got back home. I even (very unnecessarily) used my wife&#x2019;s hair dryer on a few of the components. The weather has been cold since then; we haven&#x2019;t been able to quite kick all the ice from the roads. I haven&#x2019;t been back out on the bike.</p>
<p>But I&#x2019;m excited for the next time the weather clears.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>&#x201C;Harry was used to spiders, because the cupboard under the stairs was full of them, and that was where he slept.&#x201D; - <em>Harry Potter and the Sorcerer&#x2019;s Stone</em>, J.K. Rowling<a href="#fnref1" class="footnote-back" role="doc-backlink">&#x21A9;&#xFE0E;</a></p></li>
<li id="fn2"><p>I realize now that some of the difficulty comes from the many ways parts can be sold. ex. You might buy a chainring as part of a full groupset (which can have any number of parts), as part of a crankset (which may or may not include a bottom bracket), or as an individual part.<a href="#fnref2" class="footnote-back" role="doc-backlink">&#x21A9;&#xFE0E;</a></p></li>
<li id="fn3"><p>I only needed these because I was converting an old bike frame that expected downtube shifters. I could have bought new downtube shifters but I wanted the fun brake/shifter combinations because I want to feel like <a href="https://en.wikipedia.org/wiki/Jonas_Vingegaard">Jonas</a>.<a href="#fnref3" class="footnote-back" role="doc-backlink">&#x21A9;&#xFE0E;</a></p></li>
<li id="fn4"><p>Another thing I learned the hard way: there are two bike pedal thread sizes: 1/2in and 9/16in. The 1/2s are more popular for mountain bikes. Most road bikes use 9/16s.<a href="#fnref4" class="footnote-back" role="doc-backlink">&#x21A9;&#xFE0E;</a></p></li>
</ol>
</section> ]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[ jstimer ]]></title>
    <link href="https://dcheno.work/jstimer/"/>
    <author><name>dcheno</name></author>
    <updated>2025-07-20T00:00:00Z</updated>
    <id>https://dcheno.work/jstimer.html</id>
    <content type="html"><![CDATA[ <p>Last year I had to do a little PT. The regimen consisted of a few reps of several difference exercises, each with different lengths of active and rest periods, many of them quite short.</p>
<p>I quickly got tired of hitting the &#x201C;lap&#x201D; button on the iOS stopwatch.</p>
<p>I&#x2019;m sure there are apps that do timers like this, but I figured it wouldn&#x2019;t be too hard to build, and I like having control. I didn&#x2019;t need anything fancy, just a few features:</p>
<ol class="incremental" type="1">
<li>Set different lengths for active and rest periods</li>
<li>Audible sounds for when I should start the exercise, when I should rest, and when the rest was almost over.</li>
</ol>
<p>There are several corner cases I&#x2019;ve decided to put off solving. But it mostly does what I need. When I first started I just opened up a new tab for each exercise, but I&#x2019;ve recently added the ability to save and reload timers.</p>
<p>You can try it out at <a href="https://jstimer.dcheno.work">jstimer.dcheno.work</a>.</p>
<h1 id="technical-stuff">Technical Stuff</h1>
<p>I packed all the CSS, JS, and HTML into one file. If they let you put <code>style</code> and <code>script</code> tags in HTML I figure they expect you to use them.</p>
<p>The JavaScript is a bit of a mess. I&#x2019;d like to separate display and logic a bit, but I also don&#x2019;t want to over-invest.</p>
<p>I recorded the sounds on GarageBand. I&#x2019;d love to have something better so feel free to suggest alternatives. My main goal is to be able to do simple exercises without looking at the clock.</p> ]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[ Greenlight ]]></title>
    <link href="https://dcheno.work/greenlight/"/>
    <author><name>dcheno</name></author>
    <updated>2025-07-19T00:00:00Z</updated>
    <id>https://dcheno.work/greenlight.html</id>
    <content type="html"><![CDATA[ <p>This may be a sign of boredom, but recently I&#x2019;ve been taking a lot of those one minute online typing tests. They&#x2019;re mostly the same. You get a blinking cursor and a line of random words. You type. You try not to make mistakes. At the end you get a WPM score.</p>
<p>These tests are fun, but I started to wonder: how well does typing random words quickly translate into typing actual prose quickly? Real sentences aren&#x2019;t random. Typing speed isn&#x2019;t just about knowing where the keys are. It&#x2019;s about internalizing common patterns until your fingers can carry them out without thought<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>.</p>
<p>This reminded me of a story about Hunter S. Thompson. Early in his career, he typed out the entire text of <cite>The Great Gatsby</cite> and <cite>A Farewell to Arms</cite>. He thought this would help him internalize Fitzgerald and Hemingway&#x2019;s prose styles.</p>
<p>Then I remembered that <cite>The Great Gatsby</cite> is now in the public domain.</p>
<p><a href="https://greenlight.dcheno.work/books/the-great-gatsby">Greenlight</a> is a typing test of sorts. Or a writing exercise. Or just a nice way to change up how you engage with a book for a little bit.</p>
<p>I tried as much as I could to keep the text as I found it. But I did make one major change: I replaced any special characters or accented letters with their closest standard equivalents. I know this changes the meaning, but I do not expect most US users will have these characters readily available on their keyboards.</p>
<p>Credit of course, to F. Scott Fitzgerald.</p>
<p>(Greenlight does not work with virtual (mobile) keyboards or narrow screens).</p>
<hr />
<h2 id="technical-stuff">Technical Stuff</h2>
<p>Greenlight is a static website served over Cloudflare pages.</p>
<p>I wanted to avoid having a frontend build, so it&#x2019;s just vanilla JavaScript. I doubt I followed JavaScript standards very well.</p>
<p>I used a CSS animation to make the 3 loading dots blink in and out at the beginning, but with the small payload of the site, I don&#x2019;t know how many folks will really get to experience that.</p>
<p>When I started, I thought one of the challenges would be figuring out how to lazily load the text of the book. But <cite>The Great Gatsby</cite> is a pretty trim novel. And I forgot how little space text takes up on disk.</p>
<p>The full JSON file of the text broken up into lines is only 368KB. Even on a fairly slow connection that doesn&#x2019;t seem worth breaking up. So I decided to load the whole text on startup.</p>
<p>Early on I didn&#x2019;t bother to break the text up by line, but only by paragraph, relying on CSS to set the line length where I wanted. This mostly worked, but I noticed that as the span which identified the cursor changed, it would occasionally shift the line wrapping behavior. So I ended up breaking it down line by line when I parsed the text into JSON.</p>
<p>I had planned on storing bookmarks in cookies, but they don&#x2019;t exactly fit there. I don&#x2019;t want them to expire with a session or at a specific time. So I tried out the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage">local storage API</a> instead. I liked the simplicity of it, especially for something like this, where a) long term persistence is nice, b) I don&#x2019;t intend to ever track user sessions on my end, and c) it&#x2019;s hardly the end of the world if data is lost.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>There&#x2019;s one test I particularly like called <a href="https://problemwords.com/">problemwords.com</a> which addresses this in a different way: it keeps track of words you&#x2019;ve messed up in the past and pushes them back to you until you get them right. Kind of an ANKI for typing.<a href="#fnref1" class="footnote-back" role="doc-backlink">&#x21A9;&#xFE0E;</a></p></li>
</ol>
</section> ]]></content>
  </entry>
</feed>
