DEV Community

David
David

Posted on

What I learned building a real app with Claude Code

Why I built it

I recently finished The Complete Claude Code & Claude Cowork Masterclass. A course shows you what Claude and Claude Code can do. It doesn't show you what it's like to lean on that tool for a real project, with real bugs and real releases. I wanted to find out.

I had a real problem to use. When I moved my laptop from Windows to Linux, the thing I missed most was WinSCP: my files on the left, the server's on the right, drag a file across, done. There are good file-transfer tools on Linux, but none felt like that to me.

So that became the project. The result is ShuttleSCP, a free, open-source SFTP, SCP and FTP/FTPS client for Linux, macOS and Windows, written in Rust with GTK 4. It's a public beta at version 0.13.0. This is what I learned getting it there.

ShuttleSCP resuming an upload of three files: local files on the left, the server's on the right, each transfer with its own pause and stop buttons

How we split the work

The short version: I decided and checked, Claude wrote the code.

My background is databases and IT infrastructure, not Rust. So I worked the way I would with a capable contractor. I described what I wanted in plain words, it built it, and I tried it. A typical request looked like this one:

Can we add drag and drop? Files within a pane can be dropped into a folder. If dragging from source to target, a menu should come up asking if it's a copy or a move.

A while later there was a branch to test. I used it, said what felt wrong, and it went round again until it was right.

I also set the ground rules, and they mattered more than I expected:

  • Every feature goes on its own branch, and nothing merges until I've tried it.
  • Explain each step as you go. I wanted to learn the engineering, not just collect an app.
  • Never handle my passwords or keys. When something needed a secret, it gave me a script that asked me for it directly.
  • Be honest that an AI built this, in the README and on the web page.

I didn't read every line of Rust. I can't judge Rust idioms yet. What I did review was what each change did and why, and whether it behaved that way when I used it.

What worked

The speed is real. ShuttleSCP is now about 22,000 lines of Rust with 149 automated tests. It runs on Linux, macOS and Windows, and has had eight public beta releases. Alone, I'd still be reading the GTK documentation.

The bigger surprise was the engineering around the code. These are the parts a solo hobby project usually skips, and they got done properly:

  • CI/CD. Every pull request is linted and tested on GitHub Actions. Pushing one release tag builds, checks and publishes the Linux AppImage, the macOS disk image and the Windows installer.
  • Safe self-updates. The app checks a release manifest signed with an Ed25519 key, verifies the download's SHA-256, and swaps the file in one step.
  • Secrets in the right place. Saved passwords go to GNOME Keyring, the macOS Keychain or the Windows Credential Manager, never a plain file.
  • Release hygiene. A changelog, release notes and a security policy, from the first release.

It also checked its own work in ways I wouldn't have thought of. To review the look of every dialog, it built a debug mode that opens each window, saves a screenshot and quits. When I said the dialogs looked like old GNOME ones, it could compare before and after without me clicking through the app.

And I learned a lot. I asked it to teach as it went, and it did: why a release is tied to a git tag, what signing actually protects against, why you never reuse a version number.

What didn't

The failures were the most useful part, so here they are.

Bugs only a person finds

The tests passed and the screenshots looked fine, but using the app told a different story:

  • The first release built by GitHub Actions was missing GTK's add-ons. Icons didn't load and drawing fell back to software. It worked on my laptop because my laptop had them installed.
  • In the next release, choosing a theme did nothing, and odd colours showed under the menus. The packaging tool was quietly forcing the default theme.
  • My installed app started reporting itself as a "debug" build. Running a development copy had rewritten my desktop's launcher entry to point at itself.

Each was fixed quickly once I described it, and the first two now have automatic checks so they can't come back. But I had to notice them first.

Version numbers

I had already tagged and published 0.9.2 when more work was added under that same number. It had to ship as 0.9.3. A published version can't be reused, because installed copies may already have it. The lesson: check what's actually released before calling something "part of" a version.

Trusting the status line

At one point Claude told me it was waiting for a CI job to finish. I looked at GitHub Actions and nothing was running. The job had finished successfully, but GitHub never cleared its "in progress" label, and the AI was watching the label instead of the result. It was an honest mistake, and it was mine to catch.

What I learned about the work

Writing code turned out to be the smallest part of building software. The rest was still mine:

  • Deciding. What the app should do, what it should feel like, and what comes next. The AI offers options well, but someone has to pick.
  • Testing like a user. Every real bug above was found by using the app, not by the test suite.
  • Noticing. A wrong label, a stale status, a version that doesn't add up. Twenty years of production support helped more than any Rust knowledge would have.
  • Saying no. Some suggestions were good and still not for now. Keeping the scope small is what got releases out.

I think this way of working suits people who know a domain well and can tell when something is off, even if they don't know the language. It doesn't remove the need for judgement. It moves almost all of the work there.


What's next

ShuttleSCP stays in public beta while people try it. Next on my list:

  • Make the Linux AppImage run on older systems such as Ubuntu 22.04 and Debian 12. Today it needs a 2024-or-later distribution.
  • Keep fixing what testers find, one small release at a time.

If you use SFTP or FTP, I'd value your feedback, good or bad:

GitHub logo dsalvado / shuttlescp

A graphical SFTP, SCP and FTP/FTPS client for Linux, macOS and Windows, inspired by WinSCP. Two panes, drag and drop, resumable transfers. Rust and GTK 4.

ShuttleSCP

CI Latest release Licence: GPL v3 or later

A graphical SFTP and FTP client for Linux, macOS and Windows, inspired by WinSCP: your computer's files on the left, the server's on the right, and copying between them is a drag, a right-click or a key press away.

Written in Rust with relm4 and GTK 4.

ShuttleSCP resuming an upload of three files, with pause and stop buttons for each

Status: public beta. It is used day to day on Linux and macOS, and the Windows version is new; feedback is very welcome: please open an issue See the changelog for what each release brought.

Features

Connections

  • SFTP and SCP over SSH, and FTP with plain, explicit or implicit TLS (FTPS), in passive or active mode.
  • SSH login with a password, a private key file (OpenSSH or PuTTY .ppk, with its passphrase if protected) or the keys of an SSH agent (the desktop's; on Windows Windows' OpenSSH agent or PuTTY's Pageant).
  • Saved sites, with passwords kept in the desktop keyring…

The code is GPL-3.0. If you read Rust, a critical look at it is as welcome as one at the app.

Top comments (1)

Collapse
 
aisovereign profile image
Ananya Soni •

Great write up. Seeing people share real build experiences like this is so refreshing instead of endless theoretical fluff. The points you raised about packaging edge cases and missing GTK add ons are so relatable because environment bugs easily eat up your entire day.

As the founder and CEO of AGI Systems Directorate, I totally get the dynamic with AI coding tools too. People assume you can just blindly copy paste and ship, but using an assistant to write something can take like two days of fixing errors when you could write the whole thing cleanly by yourself in six hours. You still have to review everything with extreme care.

Anyway, stellar project in Rust. If you do not mind, can I check out the GitHub repository to dive deeper into how you set everything up? I am just curious what you are working on next. I spend most of my time building Artificial General Intelligence and exploring systems that replicate human brain architecture in AI, so seeing practical developer journeys is awesome.