Frontity Design Principles

This is just an outline of the design principles we use for Frontity yet, but is meant to become a document with a full explanation of the design principles we use to guide the framework development. These principles contain a collection of vision, goals and coding guidelines.


Primary characteristics

  • Zero config
  • Simple APIs
  • But Hackable
  • Unconstrained
  • Extensible by default
  • TypeScript first
  • Modern browser first

Frontity framework

  • Zero-config, opinionated stack

    • Webpack/Babel
    • TypeScript
    • State manager
    • CSS-in-JS
    • Code splitting
    • Head manipulation
    • React SSR and hydration
    • Node Server
    • Service Workers (not available yet)
  • Package bundler

    • Feature agnostic. All features are relegated to packages
    • Everything is a package
    • The final app is the merge of all the packages
    • All packages are equal
  • Ultra Extensible

    • Goal: As extensible as WordPress PHP themes, if not more
    • Extensible by default
    • Extensibility patterns
      • frontity.settings.js state overwrite
      • State/Actions/Libraries access
      • State/Action/Libraries mutation
      • DOM access
      • Namespaces
      • Slot and Fill
      • Priorities
    • Upcoming
      • Server middleware
      • Hooks/Filters
      • React components?
      • Child packages?
    • Always keep in mind code cannot be changed by developer
    • Take into account the site builders
  • Unconstrained

    • Surface API: simple (or even unexistent)
      • Use state for configuration
    • Low-level API: hackable, unconstrained
      • Use code for configuration
    • If surface API is not clear, built the low-level first
    • Avoid making asumptions on usage
    • Start without constrains, add them slowly over time
      • Phase 0: No constrains
      • Phase 1: Documentation / TypeScript constrains
      • Phase 2: Code constrains
  • Backwards compatibility

    • Avoid breaking changes when possible
    • But deprecate old/improved APIs following SemVer

State Manager (Frontity Connect)

  • Transparent reactive implementation of Flux
  • TypeScript first
  • As close as possible to plain JavaScript
    • Define plain JS objects
    • Avoid immutability
    • Consumers don’t need to differentiate between real and derived state
    • Allow nested derived state
  • Single source of truth
    • Promote normalization
    • Make derived stated and nested derived state first citizens
  • Extensible by default
    • Hooks/Filters
  • Allow overwrites
  • Ready for DevTools
    • Action executions
    • State mutations linked to action executions
    • Component rerenders linked to state mutations

Node Server

  • Koa server
    • Smaller
    • Simpler API
    • Async/await
    • No dynamic dependencies
  • Extensible via middleware
    • Await until a particular step
    • Expose all the pieces of SSR
  • Everything is a package
    • Render packages (AMP, PDF? XML?)
    • Headers

Performance

  • Prioritize for Modern Browsers
    • Don’t sacrifice size and perf of modern browsers
    • Look only for usability in older browsers, not feature parity
  • Prioritize in this order
    1. Final user experience
    2. Performance
    3. Developer experience
    4. Core implementation complexity

WordPress

  • Don’t reimplement WordPress features, integrate them instead
  • Work with core WordPress
    • Avoid extending/hacking WordPress as much as possible
    • Adapt Frontity to WordPress, not the other way around
  • Maintain official plugin implementations for key plugins

Coding Best Practices

  • Look for just-in-time initialization
  • Avoid defining multiple APIs/entry-points for the same purpose/data
  • Use data normalization
  • Prioritize theme DX over other packages DXs
  • Prioritize package extensibility over package DX
  • Avoid abstractions when they obscure of Frontity works
  • Always define default settings
  • Prefer object-based arguments, except for options

Developer Experience Goals

  • Everything should be as easy to learn as possible
  • Frontity should have as fewer concepts as possible
    • Avoid introducing new concepts. Instead, reuse the same concepts
    • Prioritize using the same concept in different areas over having nicer APIs
  • Stay close to the standards
    • NPM vs Yarn

TypeScript

  • A single type should be enough to define a package
  • APIs must have full TypeScript support
    • Avoid separate APIs for JavaScript and TypeScript as much as possible
    • But prioritize for JavaScript themes DX
  • Use TSDocs

Namespaces

  • Contracts between packages
  • Create and maintain official namespaces
  • Shallow dependencies: new dependency system

Roadmap

  • AMP package
  • Server Extensibility
  • Hooks/Filters
  • Frontity PHP plugin
  • Source v2
  • Frontity config file
  • Language support
  • Namespace dependency system
  • DevTools
  • Admin UI
2 Likes

We did a couple of sessions explaining them in more detail:

Session 1

Session 2

We will do another one next week and we will post it here as well :slightly_smiling_face:

2 Likes

We did another session today, this time about the extensibility patterns.

I struggled a bit to explain this. I realized that the outline was not clear enough for this part, so I have to work more on this.

Session 3