Using AI Prompts to Design a Screen

This chapter explains how to use an AI assistant to design and implement Flutter screens managed by SimpleAppState, while preserving its mental model and structural guarantees.

Rather than relying on implicit conventions, we provide the AI with a precise operational prompt that defines how state may be read, written, and updated.

This approach is especially useful when:

  • Prototyping complex screens

  • Refactoring existing widgets


Why a Dedicated AI Prompt Is Necessary

Generic AI instructions such as “write a Flutter screen” often lead to incorrect patterns, including:

  • Storing state inside widgets

  • Calling setState unnecessarily

  • Mutating values returned from slot.get()

  • Updating state during build()

SimpleAppState intentionally differs from many common Flutter state-management approaches. To avoid subtle but critical mistakes, the AI must be given explicit rules describing the state semantics.

The following prompts serve as a contract between you and the AI.


Available Prompts

The prompts are maintained in the prompt/ directory of this repository. Click the link below to open the prompt, copy its contents, and paste it as the first message to your AI tool.

File

Purpose

screen_implementation.md

Comprehensive prompt for implementing or refactoring a Flutter screen. Covers state access, updates, batch processing, CloneableFile, caster rules, persistence, undo/redo, and forbidden patterns.


How to Use a Prompt

  1. Open the prompt file linked above.

  2. Copy the text inside the code block.

  3. Paste it as the first message to your AI tool.

  4. In the next message, describe:

    • The widget tree (mock UI)

    • Which slots already exist

    • Which interactions should update state

  5. Review the generated code, focusing on:

    • Slot usage (StateSlot vs RefSlot)

    • Absence of setState

    • No updates during build()

    • Correct use of casters for typed collections

    • CloneableFile implementation if custom classes are needed

This two-step interaction produces significantly more reliable and maintainable results.


Example Second Message

In the next message, provide the AI with your existing slot definitions and a partial widget skeleton. For example:

/// Slot definition file: lib/ui/app_state.dart
import 'package:simple_app_state/simple_app_state.dart';

final appState = SimpleAppState();
final countSlot = appState.slot<int>('count', initial: 0);
final logsSlot = appState.slot<List<String>>(
  'logs',
  initial: [],
  caster: (raw) => (raw as List).cast<String>(),
);
/// Partial screen file: lib/ui/counter_page.dart
import 'package:flutter/material.dart';
import 'package:simple_app_state/simple_app_state.dart';

class CounterPage extends SlotStatefulWidget {
  @override
  List<StateSlot> get slots => [countSlot, logsSlot];

  @override
  SlotState<CounterPage> createState() => _CounterPageState();
}

class _CounterPageState extends SlotState<CounterPage> {
  @override
  Widget build(BuildContext context) {
    final count = countSlot.get();
    final logs = logsSlot.get();
    return CreatedNewWidget(); // ← ask AI to replace this
  }
}

Then ask the AI to replace CreatedNewWidget() with the actual widget tree, add button callbacks, and implement any new slots or CloneableFile classes needed for the screen.