<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wilson Shrestha</title>
    <description>The latest articles on DEV Community by Wilson Shrestha (@wilxondosm).</description>
    <link>https://dev.to/wilxondosm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4219019%2Fe5fe323c-dc28-4745-acd5-40f949b33e66.jpg</url>
      <title>DEV Community: Wilson Shrestha</title>
      <link>https://dev.to/wilxondosm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wilxondosm"/>
    <language>en</language>
    <item>
      <title>Building a Nepali Typing Tutor for the Browser: Preeti, Unicode, and Honest Speed Measurement</title>
      <dc:creator>Wilson Shrestha</dc:creator>
      <pubDate>Sat, 31 Oct 2026 13:01:19 +0000</pubDate>
      <link>https://dev.to/wilxondosm/building-a-nepali-typing-tutor-for-the-browser-preeti-unicode-and-honest-speed-measurement-4h32</link>
      <guid>https://dev.to/wilxondosm/building-a-nepali-typing-tutor-for-the-browser-preeti-unicode-and-honest-speed-measurement-4h32</guid>
      <description>&lt;p&gt;I'm Wilson Shrestha, a web developer in Kathmandu, Nepal. If you learned computers in Nepal, you probably remember Typeshala — the old blue-screen typing tutor where you drilled the same row of letters until your fingers found the home row on their own.&lt;/p&gt;

&lt;p&gt;The original software still teaches well, but it was built for old Windows. On Windows 10 and 11 it often needs extra setup to run on 64-bit systems, and it never ran on a Mac, a Linux laptop or a Chromebook at all.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://wilson.com.np/online-typeshala/" rel="noopener noreferrer"&gt;Online Typeshala&lt;/a&gt;: a free Nepali typing tutor that runs in the browser. No installer, no font setup, no account. This post is about the three problems that turned out to matter most when building it — and that any developer building a typing tutor, in any language, will run into.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 1: One keyboard, three different outputs
&lt;/h2&gt;

&lt;p&gt;Nepali has three common ways to type, and they are not interchangeable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preeti&lt;/strong&gt; — a legacy font, not Unicode. Text only &lt;em&gt;looks&lt;/em&gt; Nepali when the Preeti font is installed. Still used by older government offices and printing presses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nepali Traditional (Unicode)&lt;/strong&gt; — real Unicode text that works on websites, email and social media. Follows largely the same typewriter-style key arrangement as Preeti.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Romanized Unicode&lt;/strong&gt; — typed phonetically. Easy to learn casually, but a completely different skill from the two above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The engineering consequence: the &lt;em&gt;physical key&lt;/em&gt; a learner presses is the same, but what the software must display, check and score depends on the layout they selected. A lesson engine therefore can't hard-code "key = character". It needs a layout map per key set, and the learner's target text, on-screen keyboard and scoring all have to read from that same map.&lt;/p&gt;

&lt;p&gt;You can feel this even on the home row. In Preeti, pressing &lt;strong&gt;g&lt;/strong&gt; then &lt;strong&gt;d&lt;/strong&gt; gives you &lt;strong&gt;नम&lt;/strong&gt;, and &lt;strong&gt;k&lt;/strong&gt; then &lt;strong&gt;f&lt;/strong&gt; gives you &lt;strong&gt;पा&lt;/strong&gt;. Those early real words are exactly why the home row is taught first — the learner gets a win in the first five minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 2: Lessons need gates, not just content
&lt;/h2&gt;

&lt;p&gt;The classic tutor's method is boring on purpose: short drills, one keyboard row at a time, constant repetition. I kept that structure and made the progression explicit:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Home Row → Top Row → Bottom Row → Numbers → All Keys → Custom text + Timed test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each stage is a gate. A learner moves up only when their accuracy holds — I use 95%+ as the target before raising difficulty (there are five levels, from Easy to Master). This came from a lesson that stood out while building and testing the tool: &lt;strong&gt;people who slow down and chase accuracy first end up faster&lt;/strong&gt; than people who rush for a high WPM number on day one.&lt;/p&gt;

&lt;p&gt;The practical features that support that loop are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Row-by-row lesson sets, so new keys arrive in small pieces&lt;/li&gt;
&lt;li&gt;Live WPM, accuracy and timer, updated as you type&lt;/li&gt;
&lt;li&gt;An on-screen keyboard that highlights the &lt;em&gt;next&lt;/em&gt; key, so learners stop looking down at their hands&lt;/li&gt;
&lt;li&gt;Custom text, so learners can practise with real documents — a news paragraph, an office notice&lt;/li&gt;
&lt;li&gt;A timed test mode and a leaderboard, for exam-style practice (in Nepal, Lok Sewa computer operator preparation guides commonly quote around 25 WPM in Nepali as the target — always confirm the exact figure in the official vacancy notice)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Problem 3: Measuring speed honestly
&lt;/h2&gt;

&lt;p&gt;Typing tests do not count actual words. One "word" is a standard &lt;strong&gt;5 keystrokes&lt;/strong&gt;, including spaces. That keeps scores fair between long and short words.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scoreTyping&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grossWpm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;characters&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;netWpm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grossWpm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// accuracy needs the correct-character count, tracked while typing&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;grossWpm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;netWpm&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gross WPM&lt;/strong&gt; = (characters typed ÷ 5) ÷ minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Net WPM&lt;/strong&gt; = Gross WPM − (uncorrected errors ÷ minutes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accuracy&lt;/strong&gt; = (correct characters ÷ characters typed) × 100&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Worked example, from a 5-minute test where someone types 800 characters with 20 mistakes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gross WPM = 800 ÷ 5 ÷ 5 = &lt;strong&gt;32&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Net WPM = 32 − (20 ÷ 5) = &lt;strong&gt;28&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Accuracy = 780 ÷ 800 × 100 = &lt;strong&gt;97.5%&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exams care about the &lt;em&gt;net&lt;/em&gt; figure, so every uncorrected mistake costs speed. If your tutor only shows gross WPM, you are training learners for a number nobody will grade them on.&lt;/p&gt;

&lt;p&gt;One more trap: a Nepali WPM is not comparable to an English WPM. Half-letters, matras and conjuncts often need two or three keystrokes, and many Devanagari characters sit on the Shift layer. A 25 WPM Nepali typist is doing more work per word than a 25 WPM English typist — so benchmark your users against the right language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Letting other sites use it
&lt;/h2&gt;

&lt;p&gt;Teachers and computer institutes asked to put the tutor on their own sites, so the tool is embeddable with a plain iframe — the same pattern any small web tool can offer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://typeshala.wilson.com.np/embed"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"700"&lt;/span&gt;
  &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"border:none;border-radius:12px;overflow:hidden;"&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Typeshala Typing Tutor"&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt; &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I'd tell another developer
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick the layout problem first.&lt;/strong&gt; For non-Latin scripts, "which keyboard layout?" is a product decision, not a settings toggle. Learners who switch layouts every few days confuse their fingers and reset their progress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gate progression on accuracy, not speed.&lt;/strong&gt; Speed follows muscle memory; errors practised at speed become permanent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show net scores.&lt;/strong&gt; Honest measurement is a feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ship it in the browser.&lt;/strong&gt; Removing installation removed the single biggest barrier my users had.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can try the tutor, read the full practice plan and the 4-week routine in the &lt;a href="https://wilson.com.np/online-typeshala/" rel="noopener noreferrer"&gt;full Online Typeshala guide&lt;/a&gt; on my site.&lt;/p&gt;

&lt;p&gt;If you've built learning software for a non-Latin script, I'd genuinely like to hear how you handled layout switching and scoring — that's the part I expect to keep improving.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
