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)
Because of:
- Performance.
- Extensibility.
- Code scalibity. Promoting proven design patterns:
- Flux.
- Debug.
- Single source of truth.
- Normalization.
- Separtion of concerns.
-
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
- Surface API: simple (or even unexistent)
-
Backward compatibility
- Avoid breaking changes when possible
- But deprecate old/improved APIs following SemVer
- TypeScript: is an exception.
- Interface the main APIs through Frontity even if they come from other packages.
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
- Final user experience
- Performance
- Developer experience
- 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
- Follow, as close as possible, the names already defined in WordPress.
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