App.tsx got damaged. Found the solution

So I’ve been working with AI Studio on a large project to edit images through AI. And at some point, I got problems because the app would black out after another code change. And it was rather unpredictable as to when and why this kept happening. However, the problem was that AI Studio would generate an incomplete source file, so parts would be cut off and be gone. I had to go back to a previous checkpoint or a previous version. (There’s a button in the top-right that keeps track of versions! Yes, it has version control…)

But then I realized it. Gemini dislikes very long outputs and if App.tsx grows beyond a specific size, then it cuts off parts of the source and then it tries to fix it again. Sometimes this fix even works, but part of the functionality will be gone. (And you might not notice it!)

So, what is the solution? Simple! Tell AI Studio to make App.tsx more modular by moving code to other .ts or .tsx modules. This shrinks the size of App.tsx and thus it is more likely to fit in the output of AI Studio.

Of course, a better solution would be larger output buffers, but okay. I told AI Studio to cut my App.tsx into separate modules, which it did. And now I haven’t lost any of it any more. All this because I keep the module small.

This also applies to many other source modules AI Studio generates. A source file with lots of constants or large amounts of data can crash for the same reason. So, check the source files and make sure they stay reasonably small.

1 Like

The solution: Technical layer-based modularity

​To solve the issue of “silent truncation” and “code blackouts” caused by AI output limits, I have shifted from a monolithic file structure to a Technical Layer-based Architecture. By having the Assistant break the application into small, specialized technical subroutines (Hooks, Services, Utils, and Components), I ensure that every generated file remains well within the AI’s output buffer, preventing broken builds.

I have added this to my Custom System Instructions:

Custom system instruction: Technical layering and modularity

​Core objective
​Maintain a professional, layer-based architecture by enforcing strict Separation of Concerns. You must prevent code truncation and architectural bloat by decomposing all logic, state, and UI into small, specialized modules. Every file must have a single technical responsibility and follow standardized naming patterns.

​Technical layering & naming conventions
​Organize the codebase using the following directory structure and naming patterns. Never place logic in a file type where it does not belong.

​/components (View Layer):
​Files: [Name].tsx (e.g., ImageCanvas.tsx).
​Rule: Reserved for rendering and UI structure. If a component exceeds 500 lines or handles multiple UI sections, decompose it into smaller atomic sub-components.

​/hooks (Stateful Subroutines):
​Files: use[Name].ts (e.g., useImageEditor.ts).
​Rule: Extract all complex state logic, useEffect hooks, and React lifecycle events here. This decouples the “how it works” from the “how it looks.”

​/services (Data & External Logic):
​Files: [Name].service.ts (e.g., ImageProcessing.service.ts).
​Rule: Contains API calls, business logic, or heavy orchestrations. This layer must remain pure TypeScript with no React-specific code.

​/utils (Pure Logic Subroutines):
​Files: [Name].utils.ts (e.g., colorMath.utils.ts).
​Rule: Small, stateless, and reusable helper functions for specific calculations or data transforms.

​/types (Contract Definitions):
​Files: [Name].types.ts (e.g., Editor.types.ts).
​Rule: Centralize all Interfaces and Type aliases here to ensure a strictly typed “contract” between all layers.

​/constants (Data Externalization):
​Files: [Name].constants.ts.
​Rule: Large datasets, config objects, and static mappings belong here to keep logic files lean.

​Operational mandates for AI reliability

​Evaluate density first: Before modifying or generating a file, assess if the update will exceed AI output limits. If a file is becoming a “God File,” you must perform a technical refactor (e.g., extracting a hook or utility) before adding new functionality.

​Naming strictness: You must use the specified directory and naming conventions for every new file.

​Atomic delivery: Provide code updates in discrete technical chunks. Ensure all necessary imports, exports, and type definitions are included so the module is complete and functional upon arrival.

​Structural integrity: Prioritize the “subroutine” philosophy. If a logic block can be named and isolated, it should be its own module.

​Approval for logic shifts: If a refactor changes the underlying technical contract (e.g., changing a hook’s return signature), explain the impact and obtain explicit approval before proceeding.

How to use this

​You can copy the section above directly into the “System Instructions” field in Build mode. This will force it to stop bloating your App.tsx and start building a robust, modular system.

1 Like