# data[].attributes.blurb.html
Leading a team of engineers and maintaining a live-product means staying highly alert, high-pressure situations, making plenty decisions and while also guiding and supporting peers. There is rewarding tasks but also annoying ones. Let’s turn some of the annoying into rewarding ones.

1. The journey no developer likes or wants: Pitching a technical initiative to upper management. It’s a journey of being misunderstood, seeing technical improvements and benefits for your team being denied, while drowning in politics.

2. Maintaining your application, ensuring all aspects of operating a production app are addressed and handled can be overwhelming.

This talk aims to bring piece to these aspects. Following the idea to treat your app as a city and address the needs to keep it operable, maintainable and evolving. Being able to quickly communicate your ideas to upper management as well as fellow engineers speeds up your own workflow providing a framework for making good, better and quicker decisions.

# data[].attributes.slidedeck.data[].slides[].desc.html
The Frontend City Thomas Gossmann gos.si gos.si gossi

# data[].attributes.slidedeck.data[].slides[].desc.html
Brüssel

# data[].attributes.slidedeck.data[].slides[].desc.html
Brüssel 540 Unispin in front of the Basilique Nationale du Sacré-Cœur

# data[].attributes.slidedeck.data[].slides[].desc.html
Problem Statement We explain a technical initiative to non-tech folks We use technical language in our explanation We are not understood They approve the budget for our technical initiative They won’t - we weren’t understood Examples (Local) Refactoring Writing RFCs Change build system to Embroider/vite …

# data[].attributes.slidedeck.data[].slides[].desc.html
Example: Change Build System to Embroider/vite Arguments Questions It’s faster What will it cost us? It’s fancy How long will it take? Tree shaking Half a year to have the same situation as we have Smaller bundle size now? It’s modern How much features can be shipped instead? What’s the return of this investment?

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution: Translate “ When we can explain it to my Mum, we are good. - My Manager

# data[].attributes.slidedeck.data[].slides[].desc.html
Task Responsibility Work on the Build System Keep the Frontend Operable

# data[].attributes.slidedeck.data[].slides[].desc.html
Question What would you need to do to keep the Frontend Operable?

# data[].attributes.slidedeck.data[].slides[].desc.html
Question 2 What would you need to do to keep a City Operable?

# data[].attributes.slidedeck.data[].slides[].desc.html
The Frontend City “ We built this city We built this city of rock and roll Built this city We built this city of rock and roll

Starship

# data[].attributes.slidedeck.data[].slides[].desc.html
Infrastructure City Layout Transportation Health & Security Sport & Entertainment Education City Construction

# data[].attributes.slidedeck.data[].slides[].desc.html
Infrastructure

# data[].attributes.slidedeck.data[].slides[].desc.html
Infrastructure City Software Electricity Dependency Management Water Build System Cable Release Management Garbage Collection Automated Maintenance Systems (dep upgrades) Traffic (lights) Framework infrastructure

# data[].attributes.slidedeck.data[].slides[].desc.html
City Layout Architecture

# data[].attributes.slidedeck.data[].slides[].desc.html
City Layout: Districts Hierarchical structures for managing complexity: Districts Districts to own all coherent parts of it

# data[].attributes.slidedeck.data[].slides[].desc.html
Architecture: System Landscape Subdomains System Components C4 Model

# data[].attributes.slidedeck.data[].slides[].desc.html
City Layout: Zoning American Suburbia Strict zoning (housing, commercial, industrial) Less/No mixed zoning Car dependent city Few transportation options By Avi Waxman on Unsplash By Michael Moloney on Unsplash

# data[].attributes.slidedeck.data[].slides[].desc.html
City Layout: Zoning Medieval Europe Zoning (housing, commercial, industrial) Mixed zoning Many transportation options By Svetlana Gumerova on Unsplash Shorter travels The “walkable city” By Matt Mutlu on Unsplash By Patrick Robert Doyle on Unsplash

# data[].attributes.slidedeck.data[].slides[].desc.html
Architecture: Code Organization Car dependent city = framework dependent product Your domain defines the organization of your code (never a framework) Use architectural patterns: Clean Architecture Vertical Slice Architecture Hexagonal Architecture … Prevent Tech Debt

# data[].attributes.slidedeck.data[].slides[].desc.html
Transportation APIs

# data[].attributes.slidedeck.data[].slides[].desc.html
Transportation Modalities Public Transport Private Transport Infrastructure Transport Hubs Railway network Streets Scope of traffic Local Traffic Global Traffic Public Transport Vehicles Private Transport Vehicles Bike Unicycle Tram Feet U-Bahn Car S-Bahn Bus ICE Stations Train Stations Bus Stops Stations Parking Space

# data[].attributes.slidedeck.data[].slides[].desc.html
Transportation: APIs Public API amongst subdomains Private API within a subdomain Use architecture lint to prevent illegal connections

# data[].attributes.slidedeck.data[].slides[].desc.html
Construction

# data[].attributes.slidedeck.data[].slides[].desc.html
Construction Houses in a City are the equivalent to Features of a Product City Software Construction workers evolve their tooling Linting - as railguards for programming languages Build houses… Formatting - to have the same syntactical look … faster (faster recognition) … safer Editor integration - For instant feedback on their … accessible fingertips … more sustainable Fixtures + Mocks Frontend Workshop

# data[].attributes.slidedeck.data[].slides[].desc.html
Health & Security

# data[].attributes.slidedeck.data[].slides[].desc.html
Health & Security: City Institutions Processes Firefighters Alarms for immediate actions Hospitals Pre-warn systems Emergency Medical Services Security checks for buildings Police Alpine Rescue Service Disaster Control …

# data[].attributes.slidedeck.data[].slides[].desc.html
Health & Security: Software Institutions Error Monitoring (Sentry) Processes Vulnerability management Entire app Monitoring or Subdomains Emergency changes Resource monitoring in grafana All sorts of tests from the testing pyramid Code coverage metrics Pre warn system through @embroider/try Rollback of changes Testing procedures Bug reporting Risk management

# data[].attributes.slidedeck.data[].slides[].desc.html
Sport & Entertainment DX

# data[].attributes.slidedeck.data[].slides[].desc.html
Sport & Entertainment Panem et circenses City Sport and entertainment are the most unnecessary Software DX minor matters in a city A city would function without Citizens greatly benefit from its presence Scaling Frontend: Superchar Ember Fest

# data[].attributes.slidedeck.data[].slides[].desc.html
Education

# data[].attributes.slidedeck.data[].slides[].desc.html
Education City Software Schools Onboarding Libraries Documentation Universities Diataxis: … Tutorials How-To Guides Explanation Reference Training Learning Time

# data[].attributes.slidedeck.data[].slides[].desc.html
The Frontend City “ Take me down to the Paradise City Where the grass is green and the girls are pretty Take me home (I want you, please, take me home) - Guns N’ Roses /gossi/the-frontend-city

# data[].attributes.slidedeck.data[].slides[].desc.html
Usage We do live longer in cities, than we live in code! Documentation Hub Decision Framework Structure your documentation based on the

1. Connect an incoming request to the topic frontend city idea

2. Decide from within that topic No onboarding needed

3. Higher qualitative answers (connect to context & People feel “home” immediately and can navigate scope) 4. Higher confidence in your answers 5. Faster and more competent answers 6. Increase of trust in you

# data[].attributes.slidedeck.data[].slides[].desc.html
Example: Change Build System to Embroider/vite Task vs. Responsibility Task Responsibility Work on the Build System Keep the Frontend Operable See the task through the lens of responsibility Connect to context Reshape weight of task vs. responsibility -> Priority?

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission (Translation) Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber

# data[].attributes.slidedeck.data[].slides[].desc.html
Reason: Time and Money Savings Optical fiber has lower latency, more resilient conncetions, higher bandwidth Economic Proof on Savings N umberOf Engineers ∗ ØRebuilds/Day ∗ RebuildT ime N umberOf Engineers ∗ ØBuilds/Day ∗ BuildT ime N umberOf Engineers ∗ Ext.SocialM ediaT ime/(Re)BuildDelay CIruns/Day ∗ BuildT ime Use numbers (Re)Build time numbers with classic and embroider/vite to run a comparsion Threshhold for N umberOf Engineers to savings to become significant If saving numbers are too low/insignificant, ROI/amortisation is not of interest

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber Reasons Time and Money Savings

# data[].attributes.slidedeck.data[].slides[].desc.html
Assessment: Technical Feasibility classic Embroider (loose mode) Can we roll out fiber in the city? Can we roll out fiber in to each district? Can we roll out fiber to each street? Can we roll out fiber to each house? Embroider (strict mode) vite

# data[].attributes.slidedeck.data[].slides[].desc.html
Assessment: Technical Implementation classic Embroider (loose mode) Embroider (strict mode) Preparation: Strict Imports Prepare requirements: Strict Components/Helpers/Modifiers, use @embroider/template-tag-codemod Tasks can be parallelized Can be done by product teams Great to onboard them with the new technology Iterative learning opportunity vite

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber Reasons Time and Money Savings Method Parallelize Involve product teams Incremental Delivery & Improvements

# data[].attributes.slidedeck.data[].slides[].desc.html
Challenge: Mindset Shift ember-cli shields engineers from build system internals vite provides much more exposure bundlers/transpilers are much more closer to engineers NPM is much closer ( imports and exports fields) CJS vs. ESM CJS ESM Align with JS Ecosystem Storybook 10 is ESM-only

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber Reasons Method Time and Money Savings Parallelize JS Ecosystem Compatibility Involve product teams More OTS Solutions (JS Ecosystem compat) Incremental Delivery & Improvements

# data[].attributes.slidedeck.data[].slides[].desc.html
Ecosystem Integration Internationlization ember-intl Authentication ember-simple-auth Icons ember-svg-jar ember-phosphor-icons intl-schematic openauth-js @formatjs/intl auth.js i18next better-auth linguist passport.js globalize Polyglot.js paraglide-js The solution for all of us

# data[].attributes.slidedeck.data[].slides[].desc.html
Integration: paraglide-js services/intl.ts export class IntlService extends Service { @tracked locale = getLocale(); setLocale = (locale: Locale) => { setLocale(locale, { reload: false }); this.locale = locale; }; t<MessageFn extends (…args: any) => string>( messageFn: MessageFn, params: Parameters<MessageFn>[0], options: Options = {} ) { return messageFn(params, { locale: this.locale, …options }); } formatNumber(value: number, options?: Intl.NumberFormatOptions) { return new Intl.NumberFormat(this.locale, options).format(value); }

# data[].attributes.slidedeck.data[].slides[].desc.html
Integration: paraglide-js helpers.ts function T<MessageFn extends (…args: any) => string>( messageFn: MessageFn, options?: Options | Parameters<MessageFn>[0], params?: Parameters<MessageFn>[0] ) { return resource(({ owner }) => { const intl = owner.lookup(‘service:intl’); if (params) { return intl.t(messageFn, params, options); } return intl.t(messageFn, options); }); } export const t = resourceFactory(T);

# data[].attributes.slidedeck.data[].slides[].desc.html
Integration: paraglide-js Usage import { m } from ‘#paraglide/messages.js’; import { formatNumber, t } from ‘ember-paraglide’; <template> {{t m.greeting name=”World”}} {{t m.greeting}} </template> Paraglide compiles messages to functions (vite/unplugin plugin) The (t) accepts a function Tree-shaking unused messages away Tooling Ecosystem (UI for messages in vscode)

# data[].attributes.slidedeck.data[].slides[].desc.html
Integration: better-auth They have signals Beatiful implementation for Vue and Svelte Let’s start using signals for a similar Ember implementation … That is not a smooth experience yet Community Feedback needed: RFC #1071, RFC #1079, RFC #1122

# data[].attributes.slidedeck.data[].slides[].desc.html
Integration: better-auth class AuthService<User extends BetterAuthUser = BetterAuthUser> extends Service { client!: AuthClient; @tracked internalData?: Data<User> = undefined; get user(): User | undefined { return this.internalData?.user; } setup = (auth: AuthClient) => { this.client = auth; if (auth.useSession.value?.data) { this.internalData = auth.useSession.value.data as unknown as { user: User; session: Session }; } this.loading = !this.internalData; auth.useSession.subscribe((payload) => { if (!payload.isPending) { if (payload.data?.user && !this.authenticated) { this.#handleSessionAuthenticated(payload.data as unknown as Data<User>); } else if (!payload.data?.user && this.authenticated) { this.#handleSessionInvalidated(); } } this.loading = payload.isPending; this.internalData = (payload.data as unknown as { user: User; session: Session } | undefined) ?? undefined; });

# data[].attributes.slidedeck.data[].slides[].desc.html
Integration: better-auth class AuthService<User extends BetterAuthUser = BetterAuthUser> extends Service { requireAuthentication(transition: Transition) { return new Promise((resolve) => { if (this.authenticated) { resolve(this.authenticated); } const handleAuthentication = () => { if (!this.authenticated) { this.#attemptedTransition = transition; } resolve(this.authenticated); }; const waitUntilLoadingIsComplete = () => { if (this.loading) { return next(waitUntilLoadingIsComplete); } handleAuthentication(); }; if (this.loading) { next(waitUntilLoadingIsComplete); } else { handleAuthentication(); } });

# data[].attributes.slidedeck.data[].slides[].desc.html
Integration: better-auth very similar to ember-simple-auth user menu protected route export default class UserMenu extends Component { @service declare auth: AuthService; export default class ProtectedRoute extends Route { @service declare auth: AuthService; <template> async beforeModel(transition: Transition) { {{#if this.auth.authenticated}} {{#let (popover position=”bottom-start”) as |p|}} const authenticated = await this.auth .requireAuthentication(transition); <Button {{p.trigger}}> {{this.auth.user.name}} if (!authenticated) { </Button> this._router.transitionTo(‘login’); }
<Menu {{p.target}} as |m|> <m.Item @href=”/user/profile”>Profile</m.Item> <m.Item @href=”/user/sessions”>Sessions</m.Item> <hr /> <m.Item @href=”/user/logout”>Logout</m.Item> </Menu> {{/let}} {{else}} <Link @href=”/login”>Login</Link> {{/if}} } }

# data[].attributes.slidedeck.data[].slides[].desc.html
Icons Use Iconify Configure vite.config.js import { FileSystemIconLoader } from ‘unplugin-icons/loaders’; import icons from ‘unplugin-icons/vite’; export default defineConfig({ plugins: [ // … icons({ autoInstall: true, compiler: ‘raw’, customCollections: { custom: FileSystemIconLoader(‘./assets/icons’) } }) ] }); Usage sports.gts import import import import { Icon } from ‘@hokulea/ember’; Unicycle from ‘~icons/custom/unicycle’; Activity from ‘~icons/ph/activity’; svgJar from ‘ember-svg-jar/helpers/svg-jar’; <template> Do some <Icon @icon={{Unicycle}} /> <Icon @icon={{Activity}} /> Fallback <Icon @icon={{svgJar “unicycle”}} /> <Icon @icon={{svgJar “activity”}} /> </template>

# data[].attributes.slidedeck.data[].slides[].desc.html
Integrations with Ember Github Organization: ember-integrations Candidates: vitest-browser-ember , ember-vitepress , … Integration code is tiny glue code

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber Reasons Method Time and Money Savings Parallelize More OTS Solutions (JS Ecosystem compat) Involve product teams Integrate with JS ecosystem Incremental Delivery & Improvements Faster and cheaper development with more functionality

# data[].attributes.slidedeck.data[].slides[].desc.html
Breaking Changes? Ember Ember provides a migration path Can you migrate in time to receive future updates? Relevant: Security fixes Addons Supported Ember versions are at the will of its authors When will addon authors stop supporting Ember version x? EMBER INTEGRATION ADDONS Use tsdown over rollup ESM only type=”module” No @embroider/addon-dev

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber Reasons Method Time and Money Savings Parallelize More OTS Solutions (JS Ecosystem compat) Involve product teams Faster and cheaper development with more Incremental Delivery & Improvements functionality Risk Framework Update Continuity (security fixes) OTS Adoption (limited to legacy adoptions = higher cost)

# data[].attributes.slidedeck.data[].slides[].desc.html
Architecture: Exploit the Degree of Freedom Strict imports (template imports): Organize code by your domain Strict resolver: RFC #1132 Don’t build a car-dependent city Ember has the best template system Router: Subject of the next Edition to also build the best Router

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber Reasons Method Time and Money Savings Parallelize More OTS Solutions (JS Ecosystem compat) Involve product teams Faster and cheaper development with more functionality Increase Architectural Freedom Architectural Freedom: Build our City Risk Framework Update Continuity (security fixes) OTS Adoption (limited to adoptions = higher cost)

# data[].attributes.slidedeck.data[].slides[].desc.html
Solution Mission Technical: Change Build System to Embroider/vite City: Change connectivity from broadband (DSL) to optical fiber Reasons Method Time and Money Savings Parallelize More OTS Solutions (JS Ecosystem compat) Involve product teams Faster and cheaper development with more functionality Architectural Freedom: Build our City Risk Framework Update Continuity (security fixes) OTS Adoption (limited to adoptions = higher cost)

# data[].attributes.slidedeck.data[].slides[].desc.html
Thank You There was something about a Translation and a City There was something with vite There was something with modern Ember on vite