thaiWitter
thaiWitter was a web-based Twitter client that I have written back in 2009, when I was 16 years old.
It is one of my first project of considerable size (codebase is more than 7000 lines). It got several happy users who gave me a lot of great feedback for me to improve it. I felt really good about improving this project. They are mentioned in the Changelog page. Needless to say, this is one of the projects I’m most proud about.
But back at that time, I lacked software engineering skills. I just threw a bunch of things I learned into this project. So, the project becomes less maintainable, and eventually, I stopped maintaining it in 2013 due to its immense technical debt.
In 2018, I decided to open-source this project for posterity.

Features
Here is a list of feature with some (edited/paraphrased) testimonials (text in brackets are my interpretations).
Super smooth
thaiWitter is designed to be lightweight and very responsive. It has a lot of user interface animations that works very smoothly. It can handle hundreds of tweets on the timeline without problems.
It has a handcrafted custom scrolling equation for the smoothest timeline scrolling experience in any Twitter client.
จริงๆ thaiWitter ก็ prism ซึ่งกุอี๋แหวะ mozilla สัด แต่มันดีที่สุดแล้วอะ.........
— stay noided (@notnonene) April 9, 2014
บางคนถามว่าเล่นทวิตบนเว็บไม่ลำบากหรอ ตอบ !! ไม่ลำบากครับ เพราะผมใช้ thaiWitter .
— มิน (@minxkung) June 27, 2013
ย้ายมาใช้ thaiWitter ชั่วคราว คอมพ์กากส์.. ตัวนี้แหละลื่นสุดละ
— มด (@AdmOd) October 13, 2011
Real-time streaming
With Twitter Stream API, new tweets gets displayed instantly. This makes Twitter feel very much like a chat room, so you can keep on tweeting! Requires an extension to be able to do streaming.
เปิด tab thaiwitter ไว้ข้างๆ เม้าท์ละคร ยิ่งกว่ากล่องแชทอีกคร่ะ
— 🐟mameaw (@nimomiao) July 27, 2013
เพิ่งเคยทำ thaiwitter ติดลิมิต api ว้าาา
— 🐟mameaw (@nimomiao) July 29, 2013
ก็ที่พวกมึงตอบกันได้ช้าๆ เพราะพวกมึงไม่ใช้ thaiWitter ไง นี่กูพูดตรงๆเลยนะเนี่ย
— มิน (@minxkung) June 9, 2013
thaiWitter นี่มันเอาไว้ปั๊ป tweets ได้ดีจริงๆเลยวุ้ย หุห๊ะๆๆๆๆๆๆ
— AliceSenzeXZ™ (@AliceSenzeXZ) February 21, 2012
Simple dark theme
Designed for readability, I used a simple dark theme with a font that’s optimized for easy reading on screen (Verdana).
เล่น thaiwitter ก็ดีนะ ปิดไฟเล่นแล้วไม่แสบตาดี
— 🐟mameaw (@nimomiao) November 29, 2012
twitter client ที่ง่ายต่อการ "อ่าน" ที่สุดเท่าที่เคยใช้มาคือ #thaiWitter ...
— icez พรรคนี้นอนไม่ค่อยพอ (@icez) July 4, 2009
Natural reading flow
When you read books, you read from top-to-bottom. thaiWitter puts newer tweets at the bottom too, so you can follow the flow of the conversation in a natural way.
สุดท้ายก็ตายรังครับ รู้สึกว่า thaiWitter มันเร็วกว่า อ่านง่ายกว่า
— stay noided (@notnonene) March 17, 2013
Keyboard based
You can tweet, favorite, reply, retweet, view threads, view images, and so on... all using keyboard.
Undo Tweet
Press Ctrl+Z after tweeting to delete it tweet and put the tweet text back into the input box.
เยดดดดดด ทวีตผิด กดแก้อย่างรวดเร็ว ขอบคุณ feature undo tweet แห่ง thaiwitter
— Joshua E. (@Legatte) May 21, 2012
Keyword Highlight
You can put in a list of keywords (or people), and they will be highlighted in blue.
ชอบ thaiwitter นะ มัน highlight ทวิตคนที่เราอยากอ่านได้ด้วย
— นุ้งเตอร์ (@9terz) August 30, 2014
Custom CSS
Allows you to put your own CSS to customize the UI.
หน้าจอ #thaiWitter ของ @Iaolia456 แนวมากกกก~ pic.twitter.com/i81q3v23
— Thai Pangsakulyanont (@dtinth) December 21, 2011
my #thaiWitter pic.twitter.com/fktPkiNd
— ป.ก. (@Pickyzzz) November 7, 2011
Other features
- Desktop notifications — Get notified even when you’re working on something else.
- Show Client — See who uses what to post to Twitter.
- Auto Scrolling — Auto scroll to the bottommost tweet when loaded.
- Image Preview — View images in tweets without leaving thaiWitter.
- View Conversation — Press Shift+Enter on a tweet to view a conversation.
- User/List Timeline — Press Ctrl+U and type in the
usernameorusername/list-slugto view it. - List Updates Timeline — Press Ctrl+U and type in the
username/list-slug!to view only the latest tweet of each member in the list, sorted chronologically. Very useful if you have a list of your friends and want to see what they up to after you haven’t used Twitter for a while. - Retweeting — thaiWitter supports retweeting, years before Twitter finally implemented it. You can even retweet private tweet or even direct messages (but it will give you a warning.)
- Mutated tweet (MT) — In Thai Twitter culture around that time, it’s common to retweet someone, but modify the text a bit for humorous effect. thaiWitter has a feature to track down the original tweet.
- Mention Highlight — Tweets that mention your name will be highlighted in red.
- Filter Keywords — Filter out some keywords from your timeline.
- Hardcode Mode — Removes the top bar and tweet input area at the bottom (you have to remember the keyboard shortcut). Start typing to activate the tweet input box.
- Smart Username Autocomplete — Completes the user name as you type. It uses an algorithm to determine who you might want to tweet to the most, and rank the suggestions accordingly.
- Lots of easter eggs. Can you find them all?

Tech stuff
This project is developed from 2009 to 2013. Here are some interesting technical information:
Client
No 3rd party frontend framework. I manage all DOM elements manually, but this gave me complete control of DOM animations, which allowed me to optimize the performance as I wish. (Back at that time, it’s very hard to create smooth animations. CSS transitions and animations didn’t exist back then.) It can handle up to around 10,000 tweets while performing reasonably well, while many other Twitter clients would stutter severely when there are thousands of tweets.
My thaiWitter window contains 6,666 tweets in the timeline but it’s still running smoothly.
3rd party front-end libraries:
- q, a promise library.
- underscore.
Self-written front-end libraries:
- DtJS 2, a rewrite of DtJS, my web animation framework and utility functions for front-end programming in 2009 era. Provides change observer, DOM node generator, animation system, DOM utilities (element/scrolling/viewport size/position queries, events), AJAX, JSONP, and color manipulation.
- twcs, thaiWitter Class System.
- T.js, my utility library, provides function generators, JSON parser, change observer, digit padder, date formatter/parser, and tweet parser.
Frontend code is written in a custom compile-to-JS language, thaiJS, which adds classes (transpiles to twcs), method binding, protected and private fields to JavaScript. The compiler is written in CoffeeScript and is 260 lines long.
At first I thought this was a good idea. Back then there is not many JS tooling. JSHint was not released back then. So I only need to create a transpiler and Vim syntax file and that would be it.
Nowadays, there are many tools like ESLint, Babel, and free modern IDEs that offers JavaScript IntelliSense. They won’t work with thaiJS.
6000 lines of code in one file.
I even implemented support for touch scrolling in iOS 3.x, which required me to implement touch handling and momentum scrolling myself, as
-webkit-overflow-scrollingdidn’t exist yet.No automated tests. This is one of the big reason I cannot keep maintaining this. As I add more feature and code gets more complex, I become less confident in changing code.
Lots of monkeypatching. To avoid changing old code, I try to adopt an approach where I don’t have to modify old code, but writing new code to patch old code at runtime. I thought it would be great. As it turned out, it leads to even harder maintenance.
No module system. Most stuffs are declared as global variables.
Server
- Node.js based.
- Development server with server module reloading on each refresh (no need to restart the server. Just save and refresh like PHP).
- Self-written asset pipeline. On development, compile on the fly. On production, compile and save in memory, so that the whole app can be served without disk I/O.


Screenshots

— Thai Pangsakulyanont (@dtinth)
— ป.ก. (@Pickyzzz)