# Architecture The app state is the center of a Simi app. You turn any struct/enum into a Simi app by implementing `Application` trait for it: ```rust enum Msg { Msg1, Msg2(i32), } #[simi_app] struct AppState { } impl Application for AppState { type Message = Msg; type Context = (); type Parent = (); fn init() -> Self { AppState; } fn update(&mut self, m: Self::Message, cp: ContextPlus) -> UpdateView { match m { Msg::Msg1 => {}, Msg::Msg2 => {}, } true } fn render(&self, RenderContext) { application! { "Hello world" } } } ``` You must define 3 different types required by `Application` trait: `Message`, `Context` and `Parent`. A useful app requires at least `Application::Message` to request a change in the app state (`Application::Context` and `Application::Parent` are optional). Any messages will be processed by `Application::update`, in which the app state may change. If `Application::update` return `true` then `Application::render` will be executed. Does Simi have an architecture? I am not sure! But Simi force you to separate your app into 3 parts: 1. `Application::update`: Updating the app state. 2. `Application::render`: Rendering the app view. * `Application::render` allow you to send messages back to your Simi app via element events such as `onclick`, `onchange`... The messages is just a simple enum variant, such as `Msg::Msg1` or `Msg::Msg2(42)`. Nothing more than that. Simi does not allow putting complex code in `Application::render` - the main task it does must be **render the view**. 3. `Application::Context`: Interacting between a Simi-app and outside world (another Simi-sub-app, or JS events such as callback from `setInterval`) * At least, that what I want. You can still do everything with the `Application::Context` in `Application::update`. But if it is not a simple task (for example, it requires 3 or more lines of code), it may better move the code into method in `impl Context {}` and call the relevant method.