SecretoCho
menu

· 10 min

Three flats and a platform

€320 to host one guest, almost nine months waiting for an address: renting in Serbia as a foreigner, and the property platform it led to.

Part 1 of 7 in the Building Novi Kvadrat series.

Novi Kvadrat is a property platform for Serbia, in five languages: new builds, resale and rentals in one place. It lives at novikvadrat.rs, still in beta. I’m its designer and developer, and one of the people who started it. Its first commit landed on 12 December 2025.

This series is the honest version of how it got built: the research before the screens, the design before the plans, the five languages, the studios, the bugs that never threw an error, and the hours. Part 1 is the why and the start. The why starts with three flats, and with the fourth one I found the hard way.

Three flats

I moved to Serbia from Vietnam. When I came here, I was shocked in many ways. Houses are extremely expensive for what you get. Arrogant landlords.

At my first flat the rent was €1,000, and with the other costs it came to €1,300 in total. The flat was good, but it was almost empty. Nothing useful in it.

Then I moved. At the second place the rent was cheap, €650, but the quality of the flat was too bad. My landlord kept me waiting, multiple times, to register my address. He said he wasn’t responsible for it. I waited almost nine months.

Then I moved again. The third house was good, and big, but everything inside was old. The owners were good at the beginning, and then they changed toward us. One guest came from Turkey. The landlord asked me to pay €200, and then €30 for each day until the guest was gone. I paid €320 for having my guest in the place I was renting. She was so arrogant.

I was exposed to racism in Serbia. The older generation is really problematic for foreigners.

When I looked for a house to rent, and for other things, I saw so many issues, so many problems. I spent hours, days, finding a good place. That’s why I am trying to build a platform that solves all the issues I faced, and that many other people have faced.

the rentthe placethe landlord
first flat€1,000, and €1,300 in total with the other costsgood, but almost empty—
second flat€650, cheapthe quality too badalmost nine months of waiting to register my address
third flat—big, but all old inside€320 for one guest: €200, then €30 a day
fourth flat€750all of it better; calm, quiet, a mall, a gym and shops nearbykind, with respect; we talk well

The diagram, step by step:

  1. The first flat: €1,000 rent, €1,300 in total with the other costs. Good, but almost empty.
  2. The second: cheap at €650, but the quality was too bad. I waited almost nine months for the landlord to register my address.
  3. The third: big, but everything inside was old. For one guest from Turkey, the landlord asked €200, then €30 a day: €320 in all.
  4. The fourth, today, in a smaller city near Belgrade: €750, everything inside better, calm and quiet. The owner is respectful and kind.
the first three cost me months and money. the fourth i found the hard way.

The fourth flat

Today I rent my fourth flat, in a smaller city close to Belgrade. The rent is €750. That may be expensive for a city like this, but everything is so much better: the furniture, the oven, the microwave, the fridge, the TV, the washing machine, the furnishing. You can count every item, and every one is better. The owner is extremely good: respectful and kind, the kind of landlord that is hard to find in Serbia. A big shopping mall, a fitness centre and several supermarkets are nearby, and the place is calm and quiet.

I found it because I learned the hard way. Every move before it cost me a lot of money: the moving itself, deposits I never got back, headaches, and registering at a new address all over again.

One more thing I learned in Serbia: if you want something done early and on time, you need good relationships. My current landlord is very good at that. We communicate well, so things get done sooner. Maybe that’s also because I’m in a smaller city now.

From a problem to a platform

The flats are why I care about this product. The company is why it exists.

Novi Kvadrat started because the company I work for here in Serbia started a real-estate project. After many talks with the owners, we decided to build a platform like this one. I’m one of the people who started it. The company has a founder, and the founder sets the product direction.

What the flats gave me is the other side of the listing. The site speaks five languages, and they are for foreigners like me. What five full languages cost is Part 4.

Before the first commit

Before the first commit, there was data. Interns collected it, with a guide that opened: “Welcome! This guide will help you collect real estate data for the Serbian market.” It told them what to look for: “Your job is to find information about new residential buildings (called “Novogradnja” in Serbian) and enter it into our system.” And when in doubt: “Ask your team lead”.

What they collected came into the first commit as a spreadsheet, Data Entry.xlsx, and as JSON files: 104 projects, 100 developers, 12 cities, 14 municipalities and 253 layouts. The very first project record is “Kej Garden Residence 2”, in Novi Sad.

So the market was in the repository from the very first commit, row by row.

12 December 2025

The first commit landed at 11:21, my time, on Friday, 12 December 2025. Its title was “Initial commit”, and it held 488 files and 469,101 added lines.

The app started from create-next-app. Its README still opened with “This is a Next.js project bootstrapped with create-next-app”, and the default scaffold assets were still in public/. On top sat about 45 files of app code: pages for the home, new developments by city, a project, a developer, a property and contact, an Excel import for the admin, and a first schema with eight tables. The stack was Next.js 16.0.8 and React 19.2.1, with Supabase for the data and next-intl for the languages. Claude Code was there from the start, too: the allow-list committed with it already permits npx create-next-app.

The dependency files of an older copy of the app sat beside it, in a folder misspelled old/novik-kvadrat-web: the same package list, byte for byte. So some of the work most likely started before git did.

And 374 of those 488 files were the build folder, .next. By size, that was about 55 MB of build output against about 1.7 MB for everything else. It stayed in git for five days, until “Remove .next directory from git tracking and add .gitignore” on 17 December. By then it had ridden along in later commits too, and the clean-up deleted 1,178 files.

Eleven fixes

The afternoon went to the first deploy. Next came “Add Vercel deployment guide and configuration”, its body promising to “Include troubleshooting for 404 errors and deployment setup”. Then eleven commits whose titles start with “Fix” went in, ending at 13:52 with “Fix all TypeScript build errors”.

Most of them argued with Next.js 16 about the types of one file, the locale layout. The first, “Fix Next.js 16 async params in locale layout”, made the layout async and had it await its params. Then the locale’s type went round in a circle: “Fix: Add explicit return type to generateStaticParams”, “Fix: Use explicit const assertions in generateStaticParams for Next.js type checker”, “Fix: Add explicit return type annotation to generateStaticParams”, and finally “Fix: Use string type for locale to match Next.js 16 LayoutProps type”. The carefully typed locale lost to a plain string:

// [locale]/layout.tsx, after the last of those fixes (simplified)
export function generateStaticParams() {
  return [{ locale: 'en' }, { locale: 'sr' }, { locale: 'sr-cyrl' }]
}

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode
  params: Promise<{ locale: string }>
}) {
  const { locale } = await params
  return children
}

Git doesn’t record whether the deploy went green that afternoon. The next commit came five days later.

The snippet also shows the languages of day one: English, Serbian, and Serbian in Cyrillic. Serbian was the default. Neither the Cyrillic nor that default survived, and Part 4 is the story of what replaced them.

The quiet months

The next four months were slow. From December to March the repository got 115 commits, and February had only 12. The longest silence ran 29 days, from 11 February to 12 March, and three more ran between about 17 and 21 days.

A gap in commits isn’t always a gap in work, and here I know what filled it. In those months I was working heavily on other projects in the company: not coding tasks, or small projects on the code side, and many other things on the company side.

What did get built was the foundation, and it took until 20 January. The first admin panel came on 17 December: “feat: Implement comprehensive admin panel with full CRUD functionality”. A back office for rentals, sales, payments, expenses and agents followed on 25 December. In January came the public side: a map page, rental and sale listing pages, sign-in and favorites. Then, after the long silence, neighborhoods for all 28 Serbian cities, about 170 of them, on 12 March, and on 26 March a day of 20 commits that gave the site a dark and a light theme.

Month by month: 31 commits in December, 37 in January, 12 in February and 35 in March. Then 78 in April and 190 in May. June had 43, July 191, August 102 and September 91, and October had 146 by the 19th.

December 2025
31
January 2026
37
February
12
March
35
April
78
May
190
June
43
July
191
August
102
September
91
October, by the 19th
146

The diagram, step by step:

  1. December 2025: 31 commits. January: 37.
  2. February: only 12. The longest silence ran 29 days, from 11 February to 12 March.
  3. March: 35. December to March brought 115 commits in all.
  4. April: 78. In git, the step shows from the middle of the month.
  5. May: 190, the busiest month yet. On 5 May alone, 58 went in.
  6. June: 43. July: 191, the most of any month: market statistics, then launch week.
  7. August: 102. September: 91.
  8. October: 146 by the 19th.
a slow start isn’t a verdict: four slow months brought 115 commits, and May alone 190.

Late spring

We started working on Novi Kvadrat heavily in late spring. In git, the step shows from the middle of April.

On 16 April came the scaffolding of an iOS app, inside a commit titled “Add iOS app, admin improvements, security migrations, and project assets”. On 17 April every map changed: “Replace all maps with MapLibre GL 3D and fix tile source”. German and Turkish arrived the same day, and Russian with “Add 3D building map, Russian locale, and i18n improvements”. Cyrillic had been dropped in March, so that made the five languages the site still has: English, Serbian, German, Turkish and Russian.

On 23 April the research arrived, and the portal with it. The research came first that day: competitor studies of Zillow, Idealista, Rightmove, IS24, Compass and the Serbian big three (4zida, nekretnine.rs and Halo oglasi), plus audits of our own app. The phase commits of a business portal followed that same afternoon, and the portal work ran on into early May. How that research worked, and what it changed, is Part 2.

May was the busiest month yet, with 190 commits. On 5 May, 58 went in, and it is still the busiest day in the repository.

Launch week

July had 191 commits, the most of any month. From 5 to 16 July it was mostly market statistics, built on official data. Then came launch week.

Between 22 and 29 July, 86 commits went in. On 22 July the sale page opened up as “Q0: un-gate /prodaja as honest new-construction sale browse”. The marketplaces had been built behind flags, so each launch was one constant flipped to true: “SP6: launch the sale marketplace (SALE_MARKETPLACE_ENABLED = true)” on 27 July, and “Launch the rent marketplace (RENT_MARKETPLACE_ENABLED = true)” on 28 July. One constant per launch feature turns its routes, navigation, sitemap entries and teasers on or off together.

The week had its traps. On 26 July a logo refresh left both an icon.png and an icon.svg in the app folder. Both “claim Next.js’s reserved “icon” App Router metadata convention”, and with both present, Turbopack in Next.js 16.0.8 crashed: “Fix Vercel build crash: remove duplicate app/icon.png”. On 27 July a production build died on one DNS hiccup. The build prerenders about 1,100 pages, and “Next aborts the whole export on the first prerender error”. The fix retries only network errors, and only where a replay can’t apply twice. It never retries an HTTP response, because “a 500 from PostgREST is a real answer”.

Around those launches, in late July, the site moved from its test domain to the main one, novikvadrat.rs. It’s live there, but it still isn’t fully public: Novi Kvadrat is in beta.

The route so far

After launch, the work spread out. Floor plans ran from 5 August to 13 September and went live on 13 August: traced in the browser, not recognized by a model. That’s Part 5. The design system began on 4 September, from canvas boards to a code layer, with its last phase so far on 9 October. How I work with canvases is Part 3. The studios and the 3D buildings followed from 25 September, with their latest commits so far on 18 October (Part 5 again). And the bugs that cost the most never threw an error. That’s Part 6.

first commit

main domain, late July

  1. other company work Dec 2025 – Mar 2026
  2. the foundation 12 Dec 2025 – 20 Jan 2026
  3. research and the portal 23 Apr – early May
  4. market statistics 5–16 Jul
  5. launch week 22–29 Jul, 86 commits
  6. floor plans 5 Aug – 13 Sep, live 13 Aug
  7. the design system 4 Sep – 9 Oct, so far
  8. studios and 3D buildings 25 Sep – 18 Oct, so far

The diagram, step by step:

  1. 12 Dec 2025: the first commit. Then four slow months, while I worked heavily on other projects in the company.
  2. What did get built was the foundation: an admin panel, a back office and the public side, by 20 January.
  3. 23 April: the research arrives, and the portal with it. The portal work runs on into early May.
  4. 5 to 16 July: mostly market statistics, built on official data.
  5. 22 to 29 July: launch week, 86 commits. The sale and rent marketplaces launch.
  6. Around those launches, in late July, the site moves to its main domain, novikvadrat.rs. It’s still in beta.
  7. Floor plans, from 5 August to 13 September. They go live on 13 August.
  8. The design system, from 4 September. Its last phase so far: 9 October.
  9. The studios and the 3D buildings, from 25 September. Their latest commits so far: 18 October.
the quiet months laid the foundation; after launch, the work spread out.

The team

Novi Kvadrat is the company’s product, and a team builds it. I’m the designer and developer in a core team of four, with a growth manager and two customer-relations leads who also run QA and content. The founder sets the product direction, the general manager steers, and the rest of the company gives feedback every week.

The loop is weekly. I write the code with AI agents, the two customer-relations leads run QA on what lands, and the company’s weekly feedback steers the next wave. On the front end, a team member and I check the product. Some of the feedback is small and concrete: on 28 August, feedback from the company on the blog’s category chips shipped the same day as a filter that works in place.

And the first commit, before the screens had anyone to serve, already held the interns’ guide and spreadsheet. The product started from what they entered.

My own hours are a different story, and they’re more than they should be. That’s Part 7.

What I’d pass on

Build from a pain you’ve paid for. I know what €320 for one guest feels like, and what almost nine months without a registered address costs you. When a feature is argued over, it helps to know which flat it would have fixed.

Good relationships get things done. In Serbia, if you want something finished early and on time, you need them. My current landlord communicates well, and things get done sooner.

Put the market in the repository on day one. Our first commit already held 104 projects, 100 developers and 253 layouts that interns had collected by hand. Real rows on day one are worth more than a perfect schema with nothing in it.

Check what an ignore rule actually reaches. Our first commit had a root .gitignore listing /.next/. The leading slash pins that rule to the root; the app lived one folder down, so 374 of our first 488 files were its build output anyway. The 17 December fix added a second .gitignore inside the app folder. Before a first commit, run git check-ignore -v on the build folder; if it prints nothing, nothing ignores it.

A slow start isn’t a verdict. December to March brought 115 commits; May brought 190. The months when the company needed me elsewhere still laid the foundation that the surge was built on.

When the work finally surged, research came before the portal. That’s Part 2.

The series

  1. Three flats and a platform
  2. Research before anything
  3. See it before you build it
  4. Five languages, five of every mistake
  5. Drawn, not recognized
  6. Silently
  7. More hours than I should
cd ..