Sometimes the best software ideas don’t start with a business plan, a feature list, or a fancy brainstorming session.
Sometimes they start with something much simpler.
“I just need one phone number.”
That’s exactly how this little project started.
The Problem
Earlier today, I needed to call someone.
Simple enough.
Except my phone wasn’t with me.
Normally, that shouldn’t be a big problem. Almost all my contacts are synced with Google Contacts, so technically I could just open Google Contacts on another phone, log in, search for the person, and get the number.
At least, that was the plan.
Then came the familiar sequence:
- Enter email.
- Enter password.
- Verify the login.
- Check another device.
- Approve the sign-in.
- Maybe enter another verification code.
And suddenly, getting one phone number from my own contact list felt like I was trying to access a nuclear launch console. 😄
Of course, all that security exists for a good reason. I definitely don’t want my entire Google account easily accessible from a random device.
But at that moment I realized something.
I didn’t actually need access to my Google account.
I just needed access to my contacts.
That was the problem.
And once I saw the problem clearly, the solution became obvious.
What If My Contacts Had Their Own Website?
I already self-host a number of small tools and services, so I started thinking:
What if I had something like:
contacts.example.com
- Open the website.
- Enter one simple password.
- Search a name.
- Tap the phone number.
- Done.
No Google login. No device verification. No installing an app. No complicated account recovery process.
Just an emergency address book available from any browser.
So we built it.
Keeping It Intentionally Simple
The goal was not to build another Google Contacts.
Google Contacts is already excellent at what it does.
This app solves a completely different problem.
It is basically a browser-accessible backup address book for those moments when your own phone is unavailable.
The main interface is deliberately minimal.
You log in, type a few letters of the person’s name, and the result appears immediately.
If you are opening it from a phone, you can simply tap the number and call.
Open. Search. Call.
And honestly, sometimes software becomes better by knowing what not to add.
What the App Can Do
The first version already has everything I personally needed.
- Search contacts by name, phone number, company, or other details.
- Store multiple phone numbers and email addresses for each person.
- Tap a phone number on mobile to call immediately using normal
tel:links. - Add, edit, delete, or import contacts from a separate admin area.
- Import existing contacts from Google Contacts using CSV or vCard/VCF files.
That means moving your existing contact list into the system takes only a few minutes.
View Access and Admin Access Are Separate
One thing I wanted from the beginning was to separate looking at contacts from managing contacts.
View Access
The normal login is intended for situations like borrowing someone else’s phone. After logging in, you can search and view contacts.
Admin Access
The administration section has a separate password. That is where contacts can be modified, imported, or deleted.
So even if I accidentally forget to log out on another device, I haven’t automatically handed someone the ability to modify the entire address book.
It is a small distinction, but it makes a lot of sense for this particular use case.
No Database Server Required
Technically, the project is surprisingly small.
It is built using plain PHP, HTML, CSS, and JavaScript.
- No Laravel.
- No Node.js backend.
- No Docker stack.
- No Redis.
- No Firebase.
- No giant dependency tree waiting to break because somebody released version
17.3.2-beta-final-really-final. 😄
The contact data is stored in a protected JSON file on the server.
For a personal contact directory containing a few thousand contacts, that is more than enough.
The file is protected from direct web access, and file locking is used when data is being updated.
Backing up the entire contact database is literally as simple as copying one file.
A Few Security Details
Because this application is specifically designed to be opened from devices that may not belong to you, security around sessions is important.
- Passwords are never stored as plain text; PHP’s password hashing functions are used instead.
- Secure session cookies are used when running over HTTPS.
- Administrative actions use CSRF protection.
- Login rate limiting helps reduce brute-force attempts.
- Sessions expire automatically.
- Contact pages send browser headers intended to prevent caching.
The goal is still simplicity—but simple doesn’t have to mean careless.
Obviously, I would still never recommend treating this as a replacement for your primary Google or iCloud contact synchronization.
Think of it as a secondary emergency copy.
The Funny Part: We Already Had This Problem Once
While building it, I realized this wasn’t actually the first time I had solved this kind of problem.
Some time ago, I had another issue.
There is a phone at my office that receives important SMS messages.
But sometimes I’m somewhere else and need to see a message that arrived on that phone.
So I built a small system that sends those SMS messages to my server and lets me read them from a web interface.
That became another little self-hosted tool.
Now the pattern is becoming obvious.
Office phone somewhere else?
Open the SMS dashboard.
My phone isn’t with me and I need someone’s number?
Open the Contacts app.
Instead of trying to build one enormous personal cloud platform, I’m slowly solving small problems one at a time.
And I think I actually prefer it that way.
From Personal Tool to Public Project
Initially, I built this only for myself.
But after using it, I realized the problem is probably much more common than I thought.
- Maybe your phone battery dies.
- Maybe you lose your phone.
- Maybe you leave it at home.
- Maybe you’re travelling and using another device.
- Maybe you simply want an independent backup of important phone numbers that doesn’t require logging into your primary Google or Apple account.
So I’m planning to make the application publicly available for anyone who wants to self-host it.
The demo/project will continue to be available at:
contacts.https://najad.dev
The idea is that anyone with ordinary PHP hosting should be able to upload the files, open the website, change the default passwords, import their contacts, and start using it.
- No database configuration.
- No command-line installation.
- No complicated server requirements.
- Just upload and use.
What Could Come Next?
There are already a few interesting directions this could go.
- Automatic CardDAV synchronization with a primary contact server.
- A Progressive Web App version that installs like a normal phone app.
- Encrypted backups.
- Contact groups and favourites.
- Emergency contacts.
- QR sharing.
- Temporary access links.
But I don’t want to rush into adding features just because we can.
The reason this tool exists in the first place is because I wanted something extremely simple.
Open. Search. Call.
If future features make those three steps harder, they probably don’t belong in the application.
Small Problems Make Good Projects
I think developers sometimes spend too much time looking for the next “big idea.”
- A startup idea.
- An AI product.
- The next SaaS platform.
But there are dozens of tiny annoyances in everyday life that can be solved with surprisingly small pieces of software.
This project started because I was standing there thinking:
“How do I get this guy’s phone number without my phone?”
A short while later, I had my own self-hosted contact directory.
And that’s probably the part of programming I enjoy the most.
You experience a problem.
You understand exactly why it is annoying.
And instead of accepting it, you build a tiny tool that makes the problem disappear.
Then, occasionally, you realize other people might find that tiny tool useful too.
And that’s how a one-phone-number problem became another project.
