Case · Open-source contribution
Serbian learning app: import/export and a redesign as a PWA
A public learning app for Serbian on GitHub: words with pronunciation, lessons, dialogues, tests and the alphabet – a single HTML file without a build step. I contributed two pull requests, and both were merged: a page for sharing your own learning materials and a redesign into an installable web app.

- Role
- Contributions via pull requests
- Period
- 10/2026
- Status
- 2 of 2 pull requests merged
- Stack
- HTML · CSS · JavaScript · PWA
Video: how the app works
A tour of the app
Learning, tests, dialogues, import and export, dark mode and offline mode – in English, with an AI voice-over.
Starting point
- A public learning app on GitHub for anyone learning Serbian: words by topic with pronunciation, lessons with mini tests, dialogues, tests and the alphabet.
- Technically a single HTML file with JavaScript, no build step and no server – progress and your own content live in the browser (localStorage).
- You could add your own topics and lessons but not share them with others; on a computer the interface was a narrow phone-sized column.
Pull request 1: sharing your own materials – import and export
- New “My materials” page: all your own topics, dialogues and lessons, with selection and deletion.
- Export as one JSON bundle – download it, copy it as text or send it via the phone’s share menu.
- Import from a file or by pasting: understands the bundle and the old single formats, shows what will be added beforehand, skips invalid entries and asks what to do with duplicates: replace or skip.
- Security: lessons contain HTML. Since they can now come from other people, imported HTML is sanitised – no <script>, no on* handlers and no javascript: links.


Pull request 2: redesign into an installable web app
Design
- New design system: colour tokens, the Manrope typeface, cards, shadows and calm animations.
- Dark mode: automatic like the system, light or dark.
- Phone: bottom navigation bar; computer (from 900 px): side menu and wide grids.
- Feedback while learning: animations for right and wrong answers, confetti for a good result.


New features
- “Back” works: every screen has its own address, and reloading no longer jumps to the home screen.
- Daily goal with a progress ring, a learning streak and a “word of the day”.
- Search across all words – even without special characters: “dovidjenja” finds “doviđenja”.
- Review mistakes: a separate test made of the words you got wrong; best result per topic.
- Latin or Cyrillic script – switchable in the settings or right on the flashcard.
- Pronunciation check via the microphone (Web Speech API), swipes on the phone, keyboard shortcuts on the computer, a four-week activity calendar.
PWA
- Manifest and icons: the app can be installed on phones and computers.
- Service worker: it works without internet – words you have already listened to play offline too.
Screens
Tap an image to enlarge it.

How I worked
With Claude Code: I read the app’s code and split the changes into two separate pull requests – each with a description and a checklist. Tested: every screen at 375 px width, the desktop at 1280 px, back and forward in the browser, reloading on every screen, starting offline via the service worker – and that old progress from localStorage is kept. The app stays plain HTML and JavaScript without a build step, so others can keep editing it as before.
Screenshots from the app with demo data. I translated the interface (originally in Russian) into English for this portfolio; the pull request descriptions on GitHub are in Russian.
What I bring
- Getting into someone else’s code quickly and contributing cleanly – with well-scoped, well-described pull requests.
- Frontend and UX: responsive design, dark mode, PWA and offline support – without a framework or a build step.
- Thinking about security: content from other people is checked and sanitised before it is displayed.
Open to a new position
Let’s talk.
I am looking for a permanent role in AI automation, development or AI video production – remote or on site in my region.
