I Got Tired of a Messy Desktop, So I Built FileTidy: A Native App That Organizes Your Folders in One Click


FileTidy is a native, cross-platform app that organizes messy folders like Desktop and Downloads. I built it to solve my own frustration with clutter, and it turned into one of my most useful side projects.
Ever opened your Desktop and just stared at the chaos? Random screenshots, PDFs, images, zip files, things you downloaded once and forgot?
Yeah, same here.
At some point, I realized I was wasting time manually dragging files around, renaming, and moving them into folders I barely kept organized. So I decided to do something about it.
FileTidy is a native file organizer built for macOS, Windows, and Linux.
It’s designed to help you clean up messy folders like Desktop, Downloads, or Documents with a single click.
Whether you're a developer, freelancer, or just someone who doesn’t want to manually sort files all the time, FileTidy groups your files by type and moves them into clean category folders like Images
, Documents
, Archives
, and so on.
The best part?
It’s fast
Works fully offline
And doesn’t come with unnecessary bloat
No cloud dependencies. No Electron. Just a clean native UI and a solid backend.
🖼️ Before & After
In this post, I’ll walk you through why I built it, how it works under the hood, and some of the technical challenges that made this deceptively simple tool a lot more interesting.
Why I Built It
My folders have always been a mess.
Not because I’m lazy, just because I download a lot of things while working. Screenshots, ZIP files, PDFs, videos, exports... it builds up fast. And before I know it, my Desktop looks like a scrapyard.
I tried a few tools online. Some worked, but most were either too bloated, required cloud access, or felt like they were doing too much for something that should be simple.
All I wanted was something fast, clean, and local.
Something that did one job well - organize my files without getting in the way.
So I stopped searching and just built it.
What started as a quick personal tool to clean my Downloads folder became a cross-platform app that I now use almost daily. It helped me reclaim focus, save time, and reduce friction — and it turns out I wasn’t the only one with this problem.
Stack & Tools I Used
I kept the tech stack simple on purpose. FileTidy isn’t some over-complicated system. It just needed to be fast, cross-platform, and easy to maintain. Here's what I used:
🧱 Backend & Core Logic
.NET Core — Powers the main logic. Handles file categorization, movement, retry logic, and rollback.
Everything is organized into a clean Core project that can be used by both CLI and GUI.
🖥️ GUI
Avalonia UI — A native UI framework that works across macOS, Windows, and Linux.
It gave me a clean, responsive interface without the bulk of Electron.
I used MVVM to manage state and keep the UI logic organized.
🗃️ Local Storage
SQLite — Used to persist app configuration, track sort sessions, and store rollback logs.
I created a simple store abstraction to manage the
AppConfig
and file operation history.
🚀 Automation & Deployment
GitHub Actions — I set up CI to automate builds and publish platform-specific packages:
.dmg
for macOS.exe
for Windows
Everything is versioned and tested before shipping.
This stack gave me exactly what I needed - cross-platform power, native performance, and full control over the experience.
How It Works (Architecture)
FileTidy is structured in a way that keeps things simple and maintainable. I didn’t want logic buried inside the UI or scattered across files. Everything follows a clear separation of concerns.
🧩 Core Logic
At the center of FileTidy is a reusable Core project.
This is where all the actual work happens:
Sorting and categorizing files
Skipping already-organized ones
Logging operations
Handling rollback if something fails
Managing configuration
This core is shared by both the CLI and the GUI, so the behavior stays consistent no matter how you use the app.
💻 CLI
The command-line version is a thin wrapper around the Core.
It’s ideal for quick one-liners like:
filetidy sort ~/Downloads
It prints updates to the console and exits when done. Useful for automating folder cleanup in scripts or cron jobs.
🖥️ GUI
The graphical interface is built with Avalonia UI, which made it possible to support Windows, macOS, and Linux from a single codebase.
I used the MVVM pattern to manage state, things like:
Which folder is selected
Current files in view
Whether the app is sorting
Showing success toasts or errors
Everything is reactive and async where it matters, so the UI doesn’t freeze during heavy operations.
⚙️ App Configuration
App config and sort history are stored in SQLite, via a lightweight store interface I built. It tracks:
Selected folders
Last sort session ID
Operations log (for rollback)
It’s all local, fast, and doesn’t depend on the cloud.
Live Demo
Here’s a short walkthrough of FileTidy in action. You’ll see both the CLI and the GUI version in real use — sorting real files, showing toasts, and rolling back if needed.
What you'll see in the demo:
Sorting a messy Downloads folder using the CLI
Using the GUI to pick a folder, start sorting, and see a live progress update
File categorization into folders like
Images
,Archives
,Documents
A toast notification when sorting is complete
How the revert system works.
It’s simple, fast, and works exactly how I want it to - because I built it for how I work.
Key Decisions & Tradeoffs
While building FileTidy, I had to make some early decisions to avoid overcomplicating things. These tradeoffs helped me ship faster without sacrificing reliability.
🧱 Avalonia for Native UI in .NET
Since FileTidy is built in .NET, using Avalonia UI was a natural fit.
It gave me the ability to build a responsive, native desktop interface that works across Windows, macOS, and Linux, all from one codebase.
It integrates smoothly with my existing architecture and let me apply familiar patterns like MVVM without extra overhead.
🗃️ Local SQLite over Cloud or Files
I could’ve logged operations in flat files or pushed everything to the cloud. But I wanted FileTidy to be offline-first and reliable.
SQLite gave me fast local storage with structure, perfect for storing operation logs, sort history, and user config.
🔁 No Real-Time Folder Monitoring (Yet)
I considered building a live folder watcher that would automatically sort files in the background. But for this version, I kept it manual on purpose.
This gives users more control, avoids constant file system access, and keeps the app lightweight. If real-time sorting ever gets added, it’ll be optional.
🎯 MVP First, Polish Later
There were features I could’ve added: custom rules, smart folders, UI themes, but I held off.
The focus was to ship something that worked, felt stable, and solved the original problem. No distractions. Just value.
Technical Challenges & Engineering Insights
FileTidy may look simple, but there’s solid engineering underneath to keep things smooth, reliable, and fast.
🔄 Fire-and-Forget for UI Responsiveness
To keep the UI snappy while sorting, I used a fire-and-forget approach. The GUI kicks off the sorting process on a background task without awaiting it directly, preventing any freeze.
_ = Task.Run(() => _fileTidyingService.SortFilesAsync(targetFolder, reporter));
This lets the UI stay interactive, while state updates like IsSorting
and SortProgress
are reflected in real time through INotifyPropertyChanged
.
🔁 Retry Mechanism for File Moves
If a file move fails (due to lock, permission, etc), FileTidy retries the move up to 3 times with a small delay.
for (int attempt = 0; attempt < 3; attempt++)
{
try
{
File.Move(sourcePath, destinationPath);
break;
}
catch (IOException ex) when (attempt < 2)
{
await Task.Delay(500);
}
}
This drastically reduces sort interruptions, especially for folders with partially locked files.
📝 Logging + Rollback Strategy
After each successful move, FileTidy logs the operation in SQLite so it can be reversed if needed.
await _fileOperationStore.SaveOperationAsync(new FileOperation
{
OriginalPath = sourcePath,
NewPath = destinationPath,
SessionId = currentSessionId,
Timestamp = DateTime.UtcNow
});
Rollback works by fetching all operations from a failed session and moving the files back to their original location.
var operations = await _fileOperationStore.GetOperationsBySessionAsync(sessionId);
foreach (var op in operations)
{
if (File.Exists(op.NewPath))
{
File.Move(op.NewPath, op.OriginalPath);
}
}
🧪 ISortReporter Abstraction
To decouple CLI vs GUI feedback, I created an ISortReporter
interface:
public interface ISortReporter
{
void OnStart();
void OnFileMoved(string originalPath, string newPath);
void OnError(string path, Exception ex);
void OnComplete();
}
Each frontend (CLI or GUI) implements this differently — the CLI prints to console, the GUI updates the UI and shows toasts.
🗂️ Custom AppConfig Storage
Instead of using flat config files, I built a table-backed store:
public interface IFileOperationStore
{
Task SaveConfigAsync(AppConfig config);
Task<AppConfig?> GetConfigAsync();
}
Example config values include:
Selected folders
Last used folder
Last sort session ID
Everything is stored in a local SQLite file alongside the app.
What I’d Improve
FileTidy works well for me right now, but I already have a list of ideas that would take it to the next level. Here’s what I’d improve in future versions.
🧭 Onboarding for Folder Permissions
Right now, users need to manually select folders like Desktop or Downloads — especially on macOS, where permission prompts can get tricky. A guided onboarding flow with clear instructions and checks would make the experience smoother.
👁️ Real-Time Folder Watching
FileTidy doesn’t monitor folders in the background (yet). Adding a real-time watcher that detects when new files drop in and auto-sorts them would be powerful.
But I’d want it to be:
Optional
Lightweight
Respectful of system resources
⚙️ Custom Sorting Rules
Right now, files are sorted by extension and basic metadata into fixed categories like Documents
, Archives
, and Images
.
Future versions could support:
User-defined rules (e.g. move
.zip
files larger than 100MB toHeavy Downloads
)Scheduling (e.g. sort this folder every day at 6PM)
Exclusion rules (e.g. never move
.psd
files)
🧠 Smart Folders & AI Hints
Some early concepts I’m exploring:
Suggesting cleanup actions based on file types and frequency
Auto-grouping projects or folders by recent activity
Smart undo suggestions for accidental moves
It’s early, but the potential is there, especially for users who constantly juggle design files, exports, or build artifacts.
Next Steps & Get Involved
FileTidy started as a tool I built for myself. But now, I’m opening it up — because if it helped me stay organized, it might help you too.
✅ Try It Out
I’m currently sharing early builds and updates with testers.
You can join the waitlist here:
The app runs on macOS, Windows, and Linux.
🧠 Share Ideas or Feedback
Have thoughts, bugs, or feature ideas?
You can:
DM me on X
Leave a comment under the YouTube demo
Or drop a suggestion on the waitlist page
🧪 Testers Wanted
If you love trying out raw tools or digging into edge cases and weird file system behavior, I’d really value your feedback.
This is a solo project, but I’m building in public — and every suggestion genuinely helps.
Thanks for reading.
Whether you're here to declutter or just curious about how dev tools get made, I appreciate you.
Catch you in the next one.
Subscribe to my newsletter
Read articles from Freeman Madudili directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Freeman Madudili
Freeman Madudili
Hi, I’m Freeman, a Software Developer specializing in C#, .NET, and Azure. With a passion for creating seamless web and cloud solutions, I’ve built and deployed apps that solve real-world problems. Follow along as I share insights, projects, and tips from my journey in tech!