Companies and developers are always improving their web stack with an eye on the market trends and personal experience. In this article, we will discuss the front-end stack that we have chosen in Qusion and try to demonstrate its advantages in an arguable manner.
We choose React as the main front-end framework. Why? Because the framework is popular and occupies a leading position in the big three, for a company this means that there will be specialists on the market who can be hired. A simple example, if you are a front-end developer, then you have heard about the Svelte. It fundamentally solves the problem of unnecessary abstraction of virtual dom. But if we look at it from the business side, then we will understand that a developer for this technology simply cannot be found. React also has many libraries supported by the community and companies. For business, this means reducing the cost of developing their own solutions, and for the developers, convenience.
All front-end developers in Qusion use VS Code, this allows us to write the config once and never come back to it again. The config is in the root of the project ./.vscode/settings.json. Eslint and Prettier were also needed, with their help we maintain a single code style.
All our web applications are written in Typescript, we test with Jest and Cypress, and we choose Yarn as the package manager. After we have briefly talked about developer experience, we can move on to the project structure and specific libraries that we use in our daily work.
We use Razzle as a starting point, it allows us to create a universal JavaScript application with SSR with no configuration. Razzle uses Express, Webpack and Babel so we can easily plug-in the middleware.
Our React apps are isomorphic. In an isomorphic application, most of the code should be shared - for both the client and the server side of the application. What for? How is it different from regular SSR or client rendering?
- /
- cypress/
- public/
- static/
- typings/
- src/
- server/
- graphql/
- client/
- pages/
- context/
- components/
We use GraphQL on the backend side and on the client side too - Apollo.
GraphQL is not only about reading, it's about changing data. For this, there are mutations in GraphQL. Mutations are remarkable in that we can declare the desired response from the backend, upon successful change.
Auto-generated types, queries, mutations and fragments are in graphql/ directory.
On the frontend, GraphQL doesn't have that many drawbacks, because it was originally designed to solve frontend problems. And the backend is not so smooth. They have such a problem as N + 1.
There is also the problem of deep nesting. It is solved by splitting entities into separate Query. For example, you shouldn't nest everything in the User type, split some user settings to queries for ex. notificationSettings or subscriptions. In addition you can set a depth limit on the server with the help of the GraphQL depth limit package.
We generatete types with @graphql-codegen/cli.
We use Apollo only to interact with the backend, but not as a state manager. The state is either local or in exceptional cases it is the React Context API.
To work with forms, we use Formik + Yup. The classic react-router-dom serves as a router. To write styles, we had to sacrifice a drop of performance for the sake of speed and ease of development, styled-components does it's job.
We were happy to share our front-end stack with you. In the following articles, we will look at specific tools: TypeScript, GraphQL, and others. We hope that this will help you better navigate the architecture of web applications and find useful tools.