Kofte is a knitting counter. That should be enough, but the app economy has trained people to expect a caveat. A knitting counter with social features. A knitting counter powered by AI. A knitting counter that needs an account to save your row count.
Kofte counts your rows. It tracks your stitches. It knows what a gusset is. It does not need your email address.
I wanted to build software that respects the person using it. Not in a landing-page way — in an engineering way. No telemetry. No analytics SDK phoning home while you knit a sock. No account creation screen standing between you and a row counter.
Every knitting app I found wanted something from me before it would give me something. Sign up. Subscribe. Watch an ad between your heel turn and your gusset pickup. Knitting is thousands of years old. The counter should not be this complicated.
So I built one that is not.
You create a project. You pick a template — sweater, socks, hat, scarf, blanket — or start blank. Templates give you the right parts: a sweater gets a body, yoke, and two sleeves. Socks get cuff, leg, heel flap, heel turn, gusset, foot, toe. Each part gets a counter. Tap to increment. That is the core loop.
The interesting bit is shaping. Knitting patterns are not "knit 200 rows." They involve structured increases and decreases. Increase 2 stitches every 4 rows, 5 times starting at row 10. Kofte lets you define these rules, then tracks your stitch count as you go. When you hit an action row — where you actually perform the increase or decrease — the counter lights up gold. You do not have to do the arithmetic in your head while also counting stitches.
Counters can track stitches within a row too. Set your stitches-per-row, and the counter advances the row automatically when you reach the end. Tap through your stitches, rows take care of themselves.
Zen mode. Full screen, big number. Tap anywhere to count. For when you are in the zone and do not want to think about UI.
A home screen widget. One button that increments your most recent counter. For the knitters who pick up their project for five minutes and do not want to open the app every time.
10 cottagecore themes with light and dark variants. Knitting apps should look like they belong in the craft, not in a corporate dashboard.
No internet connection. The INTERNET permission is not in the manifest.
No analytics. No crash reporting. No Firebase. No tracking pixels. No "anonymous usage
data." Your knitting data lives on your device and nowhere else.
No accounts. No sign-up, no password, no OAuth, no "continue with Google." You open the app and you are already in.
No ads. No subscription. The pro upgrade is a one-time purchase. You pay once, you own it, every future update included. The business model is: make something good enough that people want to pay for it once.
No cloud sync. Deliberate, not lazy. Your data is yours. Uninstall the app, the data goes with it. No server to breach, no database to leak, no third-party processor to audit.
Single-activity Compose app. Room for persistence, DataStore for preferences, Hilt for DI. Standard modern Android stack. MVVM with a repository layer — ViewModels expose StateFlow, the database is the single source of truth, transactions keep counter operations atomic.
The database is on version 8. Eight hand-written migrations, each tested. The schema covers projects, parts, counters, counter actions (undo history), sessions, and shaping rules. Every counter change gets recorded so you can undo it. The app keeps the last 10 actions per counter and trims the rest.
The widget uses Jetpack Glance. It queries the repository through a Hilt entry point, finds your most recent counter, renders a single increment button. Maybe 60 lines of code. Does one thing.
Session tracking remembers where you left off. Open a project and it shows which part you were on and for how long. Come back within an hour and it rolls the time into the same session. Small feature, but it matters when you knit in short bursts across a week.
Free with one project and one counter per part. Pro removes those limits and adds themes, notes, history, and the widget. Costs less than a ball of yarn.
Billing uses Google Play's billing library, which is the one place where the app touches a network — purchase verification goes through Google's servers. The purchase state caches locally in DataStore so the app works offline immediately after. Airplane mode, pro features still work. The billing library is the only dependency that phones home, and it is mandatory if you want to sell on the Play Store.
I wrote about this tension in The Platform Phones Home Anyway. You can build a perfectly private app, but the distribution platform is instrumented by default. The honest move is to acknowledge that baseline and draw a hard line at adding anything on top.
Kofte ships in 16 languages. Norwegian, French, German, Spanish, Czech, Swedish, Italian, Portuguese, Ukrainian, Icelandic, Maori, Japanese, Malay, Indonesian, and Traditional Chinese for Hong Kong. No translation service. No runtime i18n library. Android's built-in resource system and a folder per locale.
Adding a language is a content task. Translate 212 strings with correct knitting terminology, add three lines of Kotlin, done. Wrote a separate post about it: How Kofte Ships 16 Languages With Zero Libraries.
The knitting vocabulary matters. A gusset is マチ in Japanese. Yarn is 毛冷 in Hong Kong Cantonese. These are not machine translation outputs. Getting the craft words right is the difference between a localized app and one that was run through a translator.
Build what you would use. I knit. I wanted a counter that did not waste my time or leak my data. Shaping rules exist because I kept losing track of increases. Zen mode exists because I kept hitting the wrong button in the normal UI. The widget exists because I knit during conference calls and opening the full app is conspicuous.
Small software can be finished software. Kofte does not have a social feed or a pattern marketplace or AI-generated knitting suggestions. It counts rows and tracks stitches and tells you when to increase. That is enough.
Charge money for your work. Not monthly. Not with ads. A price. People who knit understand paying for good tools. A single payment respects both sides — the user is not a revenue stream, and the developer is not running a charity.
Keep your data on your device. There is no reason a knitting counter needs a server. There is no reason it needs your location, your contacts, or your advertising ID. The defaults should be private. Everything else is a choice you made on behalf of someone who trusted you enough to install your app.