Estirador

* Portuguese word; is an equipment used by architects, designers and students to support the development of technical or artistic drawings

An ever improving boilerplate that supports updates

Estirador is an upgradable boilerplate that packs most of the engineering foundations you need for a full-stack project, so you can start writing business logic right away.

Estirador allows you to work the way you were hired to: translate human concepts into code, while reusing previous work and minimizing discrepancies to improve stability.

Its structure and tooling is driven torwards allowing you to write code without much worry or double-checking.

Estirador's update system allows for multiple projects to continue having the latest changes, fixes and tools as time passes, so you can keep developing new projects while keeping old ones updated with newly adquired knowledge.

Don't like parts of the boilerplate code?
Change them, remove them, and still continue to receive updates for the boilerplate.

Want to do something similar for other projects or coding languages?
Extend it and create new boilerplates designed for your needs


Why was Estirador invented?

Estirador came from the need for developing new projects quickly, while going back to the ones already built and deployed and apply the improvements and fixes that I had learned and integrated in the newer projects, so they wouldn't get behind new technical developments, security fixes and productivity tools, or had the same features written in different ways. I also needed a way to create projects in minutes that had all my previous technical knowledge and good practices.

On top of this, clients and stakeholders generally want something in their hand, like the project's code.

Hence the need for a method to deliver new knowledge and workload in a transparent way...
... that isn't a black-box like a library or shared dependency,
... and is more flexible and has less lock-in than a low-code / no-code platform, so you can develop any type of feature the project needs without being limited by what the platform offers.

Traditional development works a lot like silos: each project (a lot of times even backend and frontend projects that have the same features) are split into individual containers of work, without any reusability of code or anything that ties and secures the data contracts between backend and frontend.
If your frontend and backend is split between two projects or teams, and one advances more than the other or forgets to report a change, it might break the whole service since both projects have now two different ways of interpreting data.
If you find some vulnerability or something to improve in one project, you have to implement it again in all your other projects. And it won't be easier. As time passes, individual projects start to become very different from each other, even thought a large chunk of features and engineering foundations (like payment gateways, security, authentication, build tools) are the same between them.
Techical debt will start to get bigger and it's hard to keep all the stability, knowledge and new features all stored in one place. As consequence, projects in the company get the "legacy" status much faster and developers will try to avoid them or do the bare minimum to close the tasks.

With Estirador, I hope we can start building projects quickly as just small layers of business logic on top of a common denominator, instead of isolated knowledge silos. Knowing we can start with no overhead and be sure past projects still have a high grade of quality for both the end-user and the developers behind it.


How does Estirador works?

Estirador exists to introduce companies to a more stable and predictable methodology of reusing and storing code, not as a framework or package with a fixed set of rules

In code, a whole project is the sum of all the workloads and changes that have happened from its beginning to the present moment. When using git, those bits of workloads are called commits.

What Estirador does is centralizing the technical related commits in a single repository and then have each project receive them as if they were day-to-day work from another colleague being merged into their current work

If you need to create a new project, instead of building the foundations from scratch with no reusability or updatability, you can pick up from the latest technical related work instead, by creating your project off Estirador, or a boilerplate that you created yourself by extending Estirador.

The default distribution of Estirador already comes packed with most of the foundations you need to start a full-stack project (database, backend, web-app) but you can always create a new upgradable boilerplate that extends the default distribution or create a boilerplate for projects with a different programming language and purpose.

Visual representation of how it works

Traditional project development workload

E-commerce Project

Added authentication
Added shopping cart
Setup E2E test suite
Fixed data auditing for GDPR
Changed landing page
Added refunds page

Fintech Project

Added authentication
Added legal fees page
Added balances dashboard
Added helpdesk service
Setup E2E test suite
Fixed data auditing for GDPR

Video Conferencing Project

Added authentication
Setup E2E test suite
Fixed data auditing for GDPR
Added webcam instructions page
Added contacts page
Fixed P2P connection error

Project development workload with Estirador

Estirador-based boilerplate

Added authentication
Setup E2E test suite
Fixed data auditing for GDPR

E-commerce Project

From estirador
Added shopping cart
From estirador
From estirador
Changed landing page
Added refunds page

Fintech Project

From estirador
Added legal fees page
Added balances dashboard
Added helpdesk service
From estirador
From estirador

Video Conferencing Project

From estirador
From estirador
From estirador
Added webcam instructions page
Added contacts page
Fixed P2P connection error

The gains from Estirador's code reusability and ability to update are even better if your company does a lot of projects for the same markets, since there are more common functionalities to be shared and worked as a whole, like payment, analytics, 3rd party services and compliance APIs.

Full features set:

High-level features

Most of the backend and frontend engineering foundations you'll need are already built in estirador's default distribution; with NestJS, Gatsby/React and Bootstrap; from bigger features to small utilities, structures and optimizations

  • Hot Reload (no need for a full restart when code is changed: state is kept, code changes are only applied to functions and visual elements):

    • Server
    • Database Migrations
    • Web app
    • Unit Tests
    • Integration Tests
    • Migration Tests
  • Test Driven Development

    • Database setup and migrations run on each test suite start
    • Tests are ready to run in parallel, meaning total test run time will be closer to the longest running test, and not to the sum of all tests, as it happens with sequencial tests
  • Auditing and compliance

    • Each database row change stores the previous version in the same table, while keeping the referencial integrity of foreign keys for the row that was just updated.
      • No need for maintaining audit tables (tables that are just clones of the real ones) with old entries that also lose referencial integrity with outside tables and always require to have matching columns with a few quirks.
      • Useful for enforcing compliance rules like GDPR and backing services that require data change history
      • Easier to debug errors, since there's a linear history
      • Can rollback a single customer's data to the previous state in case of a bug in production
  • Strict backend-frontend integration and data contracts

    Allows you to think of backend and frontend not has two separate projects, but as a single project with features that can be developed atomically (example: a single developer does both backend and frontend in one go)

    • Data structures and validations are shared between backend and frontend as if they were the same project
    • API adapters already deal with API business rules and exceptions like lack of authentication
      • API adapters include type warnings for limitations when data is passed "over the wire" / serialized

        Example: Dates are serialized as strings when send between backend and frontend and the other way around. In the backend, de-serialization of Dates is already dealt with, but on the frontend, the developer needs to manually de-serialize the date and show it in the client's timezone. The built-in API adapters remind the developer that it's not possible to receive Date objects directly from the frontend, and that the values are actually strings that need to be de-serialized. This error is common when typing new endpoints in the frontend, and might make developers lose a lot of time because they're expecting Date objects and forget that it's actually being sent as string.

    • Code sandbox: you can only import code from the backend that is stored in a dedicated shared directory. This avoid accidental import and shipping of code that contains intelectual property
  • Update system

    • Most scaffolding boilerplates are a "generate once" trick. You generate the project, but if the boilerplate is improved or fixed, you either have track down the changes and copy and paste them yourself or run code-mod scripts which a lot of times fail if you don't have your code structured in a certain way. Estirador is different, because all updates to it are git commits that can be placed on your project too. Every time estirador implements new tools, features, or fixes, you get them too by just running the update script. You could even take this to the next level and create multiple archetypes or boilerplates for your company, based on estirador. You can have boilerplates for scheduling-based apps, health-care apps, GPS-based apps, payment system apps, etc. and have updates from each of your department's boilerplate be delivered to the apps you own.
    • You can reject updates, or change them to your needs, and not be bothered again for the same update, since the update rejection stays in your project's change history
    • Avoid having deprecated dependencies. Keep them updated in a single place, increment the work everywhere
    • The update system can be detached and applied to any boilerplate repository in any language
  • Code split by feature, not by technical layer (like MVC):

    • Our jobs as developers is to translate features into code, hence it makes sense to split the workload by features, and inside the technical translation aka code
    • Its easier to spot where a fix or improvement needs to be done because we know where feature were talking about is
    • Faster to create even more estirador forks, since you can easily spot what features should or should not be included in your new boilerplate
    • Tools and practices come and go. The only constant in your project are its features.
  • Common logic like errors and loading states are dealt with automatically

    • Data that goes from backend and frontend and vice-versa has multiple states: loading, refreshing, connection failed, authentication failed, not authorized to load the data, etc. In most app development, the developers have to remember to deal with these multiple states every time they fetch content from a server or remote source, and they implement the same logic, but with different code and in multiple places. With estirador, there's a dedicated data structure for remotely-loaded data, and both the API adapters and gates deal with these states and show a predictable response to the user. No more endless loading screens when the developer forgets to implement error handling in a screen, because everything is taken care for
  • Two-token based Authentication protected against common attacks is implemented, as well as the necessary basics for Authorization and user roles

    • The first token is an ID of the session, sent in the login response body, and should be used and stored as a flag for the application to recognize if the user is logged in on not when the app starts (and then check if the token is still valid). The second one is the key to unlock the session. It's sent as an httpOnly cookie, that is inaccessible by Javascript (hence, protecting it from malicious third-party scripts that try to read it) and only sent by the browser when doing a request. You need both to be successfully authenticated. If you want to log off, you can do it even offline (something very difficult to do with httpOnly cookies, because they're not accessible to the application itself, only for outgoing browser requests), by just erasing the first token from the browser's local storage, leaving the second one, which is now useless without the first one. This second token with the session key will then be replaced in the future by another user login.
  • Designed for Typescript, with Graphql generator for Gatsby

  • Accessibility warnings

    • Like warnings that enforce the use HTML entities instead of the reserved characters
  • Eslint and Prettier setup

  • Automatic documentation of endpoints with Swagger and reflection

Low-level features

Frontend-specific features

  • Lazy loaded reducers with type-safety to avoid dispatching actions to reducers that haven't been loaded yet
  • Dark-mode and automatic text contrast detection:
    • dark-mode that isn't just an inverse blend filter and doesn't need specific color classes. In fact, you don't need to use absolute colors in almost everything. Most CSS color classes point to a color meaning (primary, danger, body, etc.) and based on the background around, they pick the best contrasting color for the text. If you're a developer, think of it as a polyfill for color-contrast() (example: the primary color might be dark blue, so you write text with the text-white CSS class. But what if there's a rebranding or a new requirement asks for multi-tenancy branding? You would have to need to change every text color reference. But not with Estirador and its Bootstrap integration)
  • Routing and authentication already integrated:
    • If a page does not require authentication, it will be server-side rendered. If it does, it will be client-side rendered, but only after fetching the current session, or terminating a session that expired.
  • Gatsby setup as main framework. Since it renders static content, any pages that does not have authentication or AJAX requests have its contents pre-rendered and ready to be consumed by search engines and link previewers like Facebook Open Graph and LinkedIn. Perfect for startups that need a landing page and an authenticated app alongside. It also includes a really code-friendly picture optimizer and cropper: you put the full-quality picture in your source code, and Gatsby will automatically output multiple pictures optimized for each device size.
    • Didn't pick NextJS because server-side-rendering has some concerns that might not be important for the project to start (that do compensate in the future), like minding the scope of the variables so you don't send the previous user's data, and CPU, networking and error handling concerns since it envolves some logic to run, instead of just fetching static files.
  • Full Redux state, local storage and session storage cleanup after user logs out

Backend-specific features

  • Docker setup
  • Environment variables validation

    No more deploy failures or runtime errors due to missing environment variables that were supposed to be set in production, but were not checked for their existance

  • Background Jobs compiled as separate files to be able to span multiple workers
  • Dev mocks so you don't need to use the real platforms during development
    • Email service mock: why spend email credits when developing when you can use a mock email service that logs and show the emails almost exactly as they are shown in the user's email client
  • Error handling
  • Settings module: useful for A/B Testing or have settings that come from the back-office
  • NestJS: Typescript backend framework that ressembles Spring Boot and provides a lot of documentation and recipes. It has dependency injection, which makes it easy to switch any module implementation depending on the environment and to override the creation of service's instances. It includes a lot of common tools and practices used in backend development. It also has a lot of reflection-based tools like automatic endpoint documentation with Swagger, by detecting class properties and return types, and supports Webpack's Hot Reload

Follow me