
The obvious version
The easiest version of SwiftApply would have been pretty simple.
Take someone's resume and job description, send everything to an LLM, generate some application material, and return it.
Technically, that works. But resumes contain a lot of personal information. Once I started thinking about that, sending everything to a server by default felt unnecessary.
So the project became less about "how do I add AI?" and more about "what actually needs to leave the user's device?"
Designing around the constraint
I started treating local storage as part of the product rather than just an implementation detail.
Information that could stay in the browser should stay there. The application could then send only the context required for a particular generation request rather than treating a remote database as the default home for everything.
That constraint made some parts of the application slightly more annoying to build, but it also made the architecture easier to reason about. There was a clear question for every piece of data: does this actually need to leave the device?
The model call is not the product
One thing these projects keep teaching me is that calling an AI model is normally the easiest part.
Most of the actual work is around it. You have to decide what information the model gets, how the user edits the result, what gets saved, what happens when something fails, and whether the generated text actually fits into the workflow.
SwiftApply was useful because it forced me to think about the boring parts. Those boring parts are usually what determine whether the thing is useful.
What I'd change now
I would make the workflow much more opinionated.
Instead of trying to generate everything, I would probably focus on a smaller number of application tasks where the system genuinely saves time.
I would also make it much clearer to the user what stays locally and what gets sent to an external model. Privacy should not just be something hidden inside the architecture. If it is part of why the product is designed a certain way, the user should be able to understand that too.
This note covers the project as described in my portfolio. The linked source and demo are the best places to look at the implementation.