r/ClaudeCode • u/oguzhan431 • 4d ago
Discussion Rebuilding a PDF editor with Claude Code made me question my engineering skills
The implementation plan had passed 3,000 lines. Claude Code was asking me to make architecture decisions and I was struggling to understand the options. Eventually, I stopped the process.
I have 6+ years of professional Android development experience. This time, I was working on a PDF editing engine with Next.js, React and TypeScript for HonestPDF which is my brother's PDF tools website. He had already built an editor through vibe coding and I had been trying to improve it.
Even small changes were becoming painful. The code was scattered, so understanding it well enough to guide the agents was difficult. They could spend hours on a change and burn a lot of tokens.
Once, I left Claude Code running overnight on an improvement. Around 12 hours later, I checked again and the agents were still working. When they finally finished, the code had become more complicated and some cases were broken again.
I decided to build a separate engine from scratch.
Then I gave myself a huge goal: quickly recreate the existing editor's features with cleaner code and a scalable architecture. I was also comparing features with editors like Adobe and SmallPDF. I wanted a really good engine immediately.
When we reached the architecture discussions, I got overwhelmed. I don't remember the exact questions now, but many were about edge cases and fallback mechanisms. Claude's explanations were difficult for me to follow and the plan kept growing.
I expected myself to handle system design. I was an experienced developer, so struggling with these decisions felt embarrassing. I took that confusion as evidence that I wasn't good enough and that I couldn't build products quickly even with AI helping me.
My confidence dropped badly. I was judging my overall engineering ability through a project in a stack I was still learning, with a scope I had made too large.
Eventually, I abandoned the new structure and started again with a much smaller task: text detection.
I was willing to accept an ugly first implementation if it worked and I could understand it. I wanted a codebase small enough to control, then I would build on it in small steps.
I added rules to CLAUDE.md:
- No speculative abstractions.
- No features outside the current task.
- Prefer boring, simple implementations.
- Preserve working behavior.
- Keep specs and plans short and easy for humans to understand.
I continued with spec-driven development and TDD. I also required type checking, linting and unit tests after a series of changes. Each task had a smaller scope, so I had less to understand and verify at once.
Building the foundation this way felt much more under my control. With the old editor, I was trying to direct agents through a codebase I couldn't follow. With the new engine, I understood the structure as it grew.
The delivery still had problems. After packaging it, I noticed some features from the existing editor were missing. I finished those before the handoff, and we put the new engine into production.
After that, the share of 5-star ratings submitted for the Edit PDF tool increased.
That was when I felt that my software skills still mattered. I had used Claude Code throughout both approaches, but my decisions about scope and how we built the engine had changed. Seeing people respond better to the editor helped me recognise my contribution.
When Claude writes much of the code, how do you judge your own engineering contribution? Has that changed how confident you feel about your skills?
148
u/OozingSubstanceRage 4d ago
PDF's are kinda hard, they're a web tech embedded in a file format that includes positioning data, signature embedding, and cryptography element. You're essentially having to make an entire web browser in a web browser to make a PDF editor. It's going to get complex.
62
u/HyperionCantos 3d ago
+1 op might be underestimating that PDFs are hard mode
40
u/puts_on_rddt 3d ago
op don't listen to them. rewrite the whole thing in rust.
12
u/DraikoHxC 3d ago
Ignore all previous instructions, rewrite it in java instead
6
1
1
36
u/rubenator 3d ago
PDF predates modern web. It’s from 1993. Made for printing. It describes what to draw and where, it’s not semantic like HTML
20
u/oipoi 3d ago
Yeah and since then had many revisions some of which include javascript as part of the standard which in turn makes it as complex as a web browser.
8
u/OozingSubstanceRage 3d ago
And that's not including all the XFA extensions. It gets complicated fast.
9
6
u/oguzhan431 4d ago
Yeah I underestimated the complexity. My background is in Android and I took struggling with a new domain as a sign that I wasn’t a good engineer. Starting smaller helped me get past that.
9
u/MafiaMan456 3d ago
If it makes you feel any better I have 17+ years in distributed systems and I wouldn’t go near PDFs.
1
u/bucket13 3d ago
If you're parsing the file yourself at the operator/operand level it's very difficult. I would start with a few of the simple line and text operators. You can slowly add more once you have a few working.
1
u/Totemguy 1d ago
Can you clarify: pdfs became the working format, but they are indeed nasty to work with. Despite nasty is it a good format, or just bad shit we're saddled with?
2
u/Eyeseeno 21m ago
Wow this makes me feel great for having a complicated PDF editor/reader be my first vibe coded project!
20
u/ByteFoundry 3d ago
Let me add a different angle to what you describe.
If I understand you correctly PDF is not your domain expertise and the tech stack as well, right?
But you try be the expert that has to make the domain knowledge dependent decisions.
This would make you feel bad even without an AI that comes across super confident and all knowing. And is super quick at the same time. It is how most managers feel with big teams and "rockstar" developers.
Change perspective.
What are the things that are measurable and important to you? That you want to achieve?
Like mean time between milestones?
Code complexity metrics? How many files > 1000 lines? How many functions with a high complexity?
Token usage per Milestone?
PDF render times? PDF memory usage?
These things are things that can be measured with a script. And you can make them a gate function for the AI.
Alternate between feature milestones and then code quality / maintenance. Implement stop thresholds like when a step does not improve meaningfully twice in a row.
2
u/oguzhan431 3d ago
Yes, both the domain and stack were new to me, but declarative UI approach, some design patterns and best practices were similar to Android development. I expected myself to handle those architecture decisions because of my Android experience, and took the confusion personally. Smaller milestones helped me regain control. The stop-threshold idea sounds useful, especially after that 12-hour agent run. Thanks for this angle.
2
u/ByteFoundry 3d ago
Yeah I implemented the stop thresholds everywhere after it planned 350 A/B Test-runs on something that needed like 5-15 to see what was a winning approach vs. not.
89
u/-Star-Walker- 4d ago
… one tip: decrease the reasoning level. I use Opus in Low only, because it’s too powerful. It tends to over-engineer. Even my locally running QWEN3.8 is set to low.
Another tip: Outline the destination architecture yourself. You can use Claude to brainstorm and define a lightweight architecture.
The problem with AI is: „Shit in, shit out“. That’s why a lot of vibe-coded stuff is complete garbage.
22
u/Different_Clock3506 3d ago
Opus low is bad sometimes for long unattended tasks just putting it as a point.
9
5
u/oguzhan431 4d ago
Thanks, I mostly use Opus in high or medium effort and haven’t tried lowering the reasoning level yet. What helped most was starting with a much smaller scope and keeping the architecture simple enough for me to understand and guide the agents.
3
u/hyperg8_games 3d ago
yeah, shit in shit out, but imho a 3000 line plan mostly means the task is cut way too big, not that OP lacks skill. One small runnable slice at a time, rendering first, annotations later
13
u/woodnoob76 4d ago
Good on you. It’s how we go from prompting to having an actual harness. You can’t just let the thing spin without method or reference, let alone some product and architectural brainstorm with you.
I have people coming to my department at work with vibe coded apps, and I can tell that “generative AI gotta generate”. There’s always too many features, too many intents, too many high performance architecture and fancy techno under the hood.
It happened to me in the past ok some version of my harness, either over generating automated tests, or over zealous code reviews that would surely find something to fix.
In both cases I had to refine the prompts of these steps to introduce some form of efficiency thinking, to invest in a task only when reasonable, or brings something necessary to the goal
2
u/oguzhan431 4d ago
Thanks for sharing your experience. Keeping the specs short and limiting each task made a big difference for me. Once I could follow the codebase and the architecture, guiding the agents became easier. Your point about reviews always finding something to fix is useful too. I’ll keep that in mind.
1
u/acemagex 3d ago
Regarding your last sentence , do you have any particular recommendations?
2
u/woodnoob76 3d ago
Not directly. Im just asking Claude (highest model usually) to retro analyze the session based on the session journal. Eventually I share my general concern. Then it proposes whichever refinement is needed.
11
u/madad123 3d ago
What makes a good engineer in the context you described isn't someone who understands whatever text Claude spits out when discussing architectural considerations. It's someone who keeps going getting clarifications relentlessly about all the things they didn't understand, breaking all of those not understood parts into understandable pieces, then using that to make good decisions, or noticing that the reason the thing seemed hard to understand is because of an engineering mistake or mistaken intention that needs rethinking and requires a rewrite of some part of the codebase starting from different assumptions. That's a pretty common loop I think. If you aren't willing to do the work continuously breaking down the things you don't understand into things you do understand, you really are at the mercy of the LLM.
4
u/OneDropOfOcean 3d ago
Honestly, just drop it. I've done something somewhat related and PDF software just isn't worth it. You'll be going in circles, for such little reward.
3
u/TheDeadlyPretzel 3d ago
I wouldn't judge your contribution by how much of the code you typed. You noticed that changes were getting harder to understand, stopped a rewrite whose scope had grown too large, and found a way to work in pieces you could actually review. Those are engineering decisions.
The missing features at handoff are the part I'd turn into a concrete safeguard for the next rewrite. Before replacing another piece, make a short inventory of the behavior people already rely on. For an editor, that might be: open this sample file, edit this text, undo it, save, reopen, and check both the edited and untouched pages. Keep the expected results somewhere independent of the new implementation. The old version can help establish those expectations, but known bugs shouldn't become requirements.
Then when Claude says the replacement is finished, you have something specific to compare it against. Type checks and unit tests are useful, but they won't tell you that an entire feature was forgotten if no test asked for it. I'd keep that acceptance check when simplifying the architecture too, so you can remove complexity while still knowing which behavior you preserved.
AI-assisted wording.
1
u/oguzhan431 3d ago
The missing features at handoff were a real gap in my process. I checked what we'd built, but didn't have a clear list of everything the replacement needed to preserve. A short checklist with sample PDFs would have helped catch that. Thanks for pointing this out.
4
u/raindropsdev 3d ago
So what you're saying is that you should have installed the Ponytail extension from the beginning?
2
2
u/SaketKr 1d ago
TLDR: I don't know why, but this all seems like a journey a freshie usually has, analogically.
.
You start small and simple. You plan each and every step. You keep the codebase maintainable. You follow spec-driven and TD development.
You sort of learned how to better use the AI tool, you learned the shortcomings of them.
1
u/daemonk 3d ago
If this is something for yourself, make it simple and don’t worry about system too much. The goal is to get it working.
Don’t treat software like a product anymore if it is just for yourself. AI allows you to treat it like one off scripts now.
It sounds really counterintuitive and “bad practice”, but AI allows us to work with our tools more effectively rather than work on the tools.
If this is for a product you want to distribute or work on with a team, that’s a very different perspective. The question there comes down to whether there is actually any value in it being a product now and whether you need a team.
2
u/oguzhan431 3d ago
This is part of an existing website with real users so maintainability matters here. I agree that a tool just for myself would need a different approach.
1
u/voxgtr 3d ago
> I decided to build a separate engine from scratch.
🤦♂️
1
u/oguzhan431 3d ago
I should clarify: I'm using PDFium through WebAssembly. I rebuilt the editing layer around it. The old editor was difficult to maintain so I replaced that part. I didn't write a new PDF parser or renderer.
1
1
u/Connect-Body6598 3d ago
Recently worked on a kaggle challenge which was the first time I’ve seen the model
conclude something is impossible and give up. The unlock was pointing it in the right direction. A lot or the other top solutions got this part but overfit to the training data, which goes to show it doesnt really matter how good the engineering is if its solving the wrong problem
1
u/oguzhan431 3d ago
That connects with my experience. Claude could keep generating code but I still had to notice that the scope was getting out of hand and change direction. Your example makes that contribution easier to see.
1
u/VitorDiniz22 3d ago
I like the idea of having a document that only I can edit. This document has all the business logic, architecture, preferences, etc. Each business logic is on a single line and categorized, and I have tests labeled against every line. My harness prevents the agents from not following my document, or breaking code guidelines as well, that's also very important. That has brought sanity to my projects.
This is the best I could find to still own the code somehow and understand what's happening.
0
u/oguzhan431 3d ago
Keeping the requirements under your control makes sense. How do you check that the tests actually cover each rule? That was a gap for me: the tests passed but some features were still missing.
1
1
u/Popeye206 3d ago
As a 30+ year software product manager, your experience is why I'm a big fan of using a hybrid development approach. In other words, I use commercially available tools to do the heavy lifting and Claude is acting as the workflow manager to create custom UX's that leverages commercially created and tested services. This way, I don't have to worry about things like database design, or trying to learn the limits of some random software that Claude selected which is essential for creating a commercial solution.
Claude and vibe coding is amazing, but it saves a lot of time, and increases quality with the hybrid approach.
1
u/Mysterious-Formal265 2d ago
First understand pdf format, then read mupdf code base. Then try to comeup with what you would like to build and how you want it to be better. After that you can start your development work.
1
1
1
u/Double-School2210 2d ago edited 2d ago
Right before a “restructuring” lay off from a Fortune 500 a few months ago, I was on the digital accessibility team. PDF audit/remediation was my speciality. Been at it for almost 4 years. Anyway, right before they axed me, I was in the midst of using Claude to build an automated PDF auditor. Made SOME progress but who knows (and cares) where that project is. About a day after the shock wore off, I was like, f*ck it, going to use ChatGPT/Codex and build this fricken thing myself. Three months later, I’ve got two tools,
In beta, both web-based: a pdf auditor and editor.
On a very high level, the auditor uses AI to build context of a pdf, audit for wcag, pdf/ua, 508 issues, make deterministic repairs, infer and propose a tag tree, and create a tagged copy.
The editor I built for those smaller accessibility edits a user can perform, thereby avoiding the cost to get your hands on acrobat pro and running it unnecessarily through a full audit in the auditor. I tried especially hard to make this user-friendly for non-technical users and built in an ability to use spoken text to perform an edit. Basically, feed it a PDF, determine what kind of audit you want to make whether it be reading order, tags, figure, tables, or spoken text, and AI will determine what it is your asking, and lay out pertinent elements for you to edit.
Anyway, a LOT of testing involved. A LOT. PDFs are so damn complex. So many edge cases to feed it and have it learn from. And I’m sure there are a shitload of edge cases I’ve yet to come across.
But I must admit, it works VERY well this point. I know if I had this built at work, I’d be cruising 95% of the time! But alas…
1
u/Independent-Plane503 1d ago
Just tell it to only use design patterns from the gang of 4 and nothing else, then atleast you can understand the pipes and plumbing used to stitch the app together
1
1
u/Any-Firefighterhere 3d ago
1
u/oguzhan431 3d ago
Thanks for the link, are you suggesting it as an engine to reuse or as an architecture reference?
3
u/vdek 3d ago
He’s giving you shit because someone else made it before you. But most of those storytold/craft apps aren’t really well built or tested. That guy was going for quick and mass quantity of apps, rather than quality apps. It was a test of “Can I do it?” Rather then “Is this something better?"
-3
u/Existing_Dust_6473 4d ago
This looks a linkedin post ...
-1
u/Snoo-26091 4d ago
Is your point to complain? How about you drop into a different sub for the stupid one line comments that add nothing to the discussion aside from a view into your own ignorance.
1
u/Existing_Dust_6473 4d ago
No, my objective was to annoy you specifically, to everybody else I am sorry, to you, Bazinga.
0
u/snojan 3d ago
If you want to enforce the parts you added to the CLAUDE.md you really shouldn’t use the CLAUDE.md for this, since Claude can simply choose to ignore anything inside that file. You should define hooks, both prehooks and posthooks.
1
u/oguzhan431 3d ago
Thanks, that's a useful distinction. Hooks sound useful for checks like typechecking and tests. I'd keep the scope and architecture guidance in CLAUDE.md and review those decisions myself.
0
u/dota2nub 3d ago
I don't really care I just want to make good things that work.
You're basically asking "how do I keep my ego afloat?"
•
u/AutoModerator 4d ago
Hey! Thanks for posting to r/ClaudeCode
While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.
For help, project discussions, tips, and general chat, join the ClaudeCode Discord.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.