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 to Heavy 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:

👉 FileTidy Waitlist

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.

0
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!