Qwik — Integraciones

Claves para aprender a trabajar con las integraciones de librerías proporcionadas por Qwik con varias funcionalidades y servicios útiles

Anartz Mugika Ledo🤗
18 min readFeb 4, 2024

En este artículo vamos a ver una funcionalidad super interesante que nos ofrece Qwik con opciones para facilitar la conexión con sus herramientas y servicios.

Una de ellas es la que hemos trabajado en un artículo anterior, donde se integraban componentes de React dentro de Qwik.

A continuación os proporciono los puntos que vamos a ver en este artículo.

Contenido del artículo

Estos pasos los vamos a completar hasta conseguir integrar nuestra propuesta de integración y lo haremos paso a paso, al detalle.

  • ¿Qué es una integración?
  • Modo de usar las integraciones.
  • Agregar una nueva integración: Leaflet Map.
  • Agregar mapas con Leaflet como integración.
  • Crear Pull Request (PR) para integrarlo al framework.
  • Conclusión.

¿Qué es una integración?

A partir de un proyecto creado con Qwik City ejecutando un comando que nos proporcionan desde el equipo de Qwik, vamos a disponer una lista extensa de opciones que nos va a permitir integrar aplicaciones de una manera sencilla dándonos la opción de poder usarlas en unos pocos pasos.

Si no usásemos una de las opciones que nos proporciona esta funcionalidad, podríamos implementar esas opciones, aunque tendríamos que ir dando los pasos de manera manual y seguramente con más probabilidades de fallar en algún paso, haciendo que su funcionamiento no fuese el adecuado.

El comando a ejecutar para poner en marcha la integración de estas funcionalidades y servicios es:

npm run qwik add

Nos pedirán que seleccionemos la integración que deseamos agregar.

Una vez que seleccionamos una integración, se va a agregar a nuestra aplicación y podremos empezar a usarla.

Prestad atención a la información que nos vayan proporcionando, que muchas veces nos ceñimos a dar a Siguiente, Si, etc. sin fijarnos en lo que hacemos y luego nos llevamos sorpresas poco agradables.

Actualmente (febrero del 2024), esta es la lista de posibles integraciones que nos proporcionan:

  • Astro
  • Auth.js
  • Bootstrap (Aportación mía)
  • Builder.io
  • Cypress
  • Icons
  • Image Optimization
  • i18n
  • Leaflet Maps (Aportación mía) (lo que vamos a ver como ejemplo en los siguientes pasos)
  • Modular Forms
  • Nx Monorepos
  • OG Image
  • Orama
  • Panda CSS
  • Partytown
  • Playwright
  • PostCSS
  • Prisma
  • React
  • Storybook
  • Styled Vanilla Extract
  • Supabase
  • Tailwind
  • Tauri
  • Turso
  • Vitest

Documentación Qwik — Integraciones

Podéis encontrar la lista de todas las integraciones oficiales de Qwik en el siguiente enlace:
https://shorten-up.vercel.app/-IllWy0Lac

En esta lista vemos un montón de opciones interesantes que nos pueden proporcionar agilidad a la hora de integrar funcionalidades en nuestros proyectos de Qwik.

Os animo a que probéis y experimentéis los resultados que nos proporcionan.

Agregar una nueva integración: Leaflet Map

Existe la posibilidad de contribuir aportando nuevas integraciones tanto en el lado servidor como librerías.

Para poder realizar el proceso para los dos casos, tenéis disponibles la siguiente información:

Agregar mapas con Leaflet como integración

En este caso, vamos a aportar lo siguiente ya que es una funcionalidad de mapas que no se ha aplicado en Qwik (actualmente ya está implementada: https://shorten-up.vercel.app/zxKLPGChPs).

Os voy a enseñar los pasos para integrar una nueva funcionalidad en este listado paso a paso.

Ideas de posibles integraciones de librerías

Podríais integrar algunos de estos ejemplos:

- Bootstrap (implementado)

- ChartJS

Solo tendríais que seguir el mismo proceso que voy a hacer a continuación en este apartado. Si tenéis sugerencias de mejoras, podéis realizarlas.

Empezamos con el proceso y lo primero que necesitamos es hacer un fork del repositorio oficial de Qwik.

Fork del repositorio

Necesitaréis tener una cuenta de Github y debéis de hacer un fork del contenido de este repositorio, para haceros una copia local en vuestra cuenta.

Cuenta de Github

¿No tenéis cuenta de Github? Debéis de crearla mediante estas instrucciones ya que este requisito es indispensable:
https://shorten-up.vercel.app/aXvVUUcUCO

Teniendo la cuenta, debemos de hacer una copia (mediante fork) del repositorio base para tener una copia como de nuestra propiedad, basándose en la base de la propuesta.

Accedemos al repositorio oficial de Qwik mediante el siguiente enlace:

https://shorten-up.vercel.app/Ig3CktZmP_

Para hacer un fork del repositorio, pulsamos en Fork en la parte superior derecha:

Y tenemos en cuenta los siguiente puntos:

  1. Nombre de usuario / organización que vamos a usar para alojar el proyecto, en mi caso con el usuario qwik-book.
  2. Nombre del repositorio. Yo no lo cambiaría, aunque si queréis poner otro nombre, adelante. Procurad que sea descriptivo.
  3. Descripción del repositorio.
  4. Para copiar solo la rama main, no hace falta más.
  5. Crear el fork para copiar el código del repositorio original.

Mientras se crea la copia se mostrará un estado similar al siguiente dando el feedback de que está en ello:

Y así estará el repositorio en nuestra cuenta (en mi caso en qwik-book) una vez realizada la copia mediante el fork:

Ya tenemos el proyecto, ahora ya iniciamos el proyecto en nuestro equipo clonándolo para trabajar en local.

Una vez clonado, abrimos el proyecto y ya empezamos con las instalaciones y configuraciones a realizar.

Creamos una nueva rama por ejemplo para leaflet-map con el nombre de la rama feature/leaflet-map-integration-adapter

Instalaciones y configuraciones iniciales

Nos basamos en lo que se especifica en el documento de contribución dentro del repositorio principal.

El enlace lo tenéis aquí, para tener a mano la referencia oficial:

https://shorten-up.vercel.app/8rgp1VgT_M

He probado las diferentes opciones y esta es la que más sencilla me ha parecido de seguir.

  • Instalamos Rust en nuestro equipo: https://shorten-up.vercel.app/vx8ZlrP-yP
  • Instalamos wasm-pack con el comando cargo install wasm-pack --locked.
  • Seleccionamos la versión Node >= 20. Ejecutando: nvm use ya seleccionamos la versión 20.11 (puede variar y por eso nos debemos de fijar en el fichero .nvmrc) que es la especificada actualmente en el proyecto.
  • Instalar pnpm en nuestro equipo: https://shorten-up.vercel.app/-kOmyBiN7c
  • Instalamos las dependencias del proyecto ejecutando: pnpm install

Desarrollando nueva funcionalidad

Una vez realizados los preparativos para poder trabajar dentro de este repositorio vamos a comenzar dando los pasos para generar una nueva funcionalidad que servirá como integración en Qwik, con el objetivo de facilitar el desarrollo de cara a comenzar a trabajar con mapas (o futuras funcionalidades que creamos interesantes).

Creando lo básico

Accedemos a ./starters/features y creamos un nuevo directorio llamado leaflet-map:

Procurad que el nombre del directorio sea lo más descriptivo posible para que sea fácil de identificar entre la multitud de directorios.

Ahora que ya tenemos el directorio creado, debemos de añadir el un nuevo fichero package.json que será super importante, para añadir los datos fundamentales de esta integración.

Vamos a starters/features/leaflet-map y dentro creamos el fichero package.json con el siguiente contenido:

{
"description": "Use Leaflet Maps in your Qwik app",
"__qwik__": {
"displayName": "Integration: Leaflet Maps",
"priority": -10,
"viteConfig": {},
"docs": [
"https://leafletjs.com/reference.html",
"https://leafletjs.com/examples/quick-start/",
"https://www.sitepoint.com/leaflet-create-map-beginner-guide/"
],
"nextSteps": {
"lines": [
"We start the project with `npm start`.",
"Once started, we access the /basic-map path to see the demo example.",
"You can make changes and experiment within src/routes/basic-map/index.tsx",
"to add a new location, zoom,... and any improvements to the maps component",
"can be done in the src/components/leaflet-map/index.tsx section.",
"Have a look at the docs for more info:",
" https://leafletjs.com/"
]
}
},
"dependencies": {
"leaflet": "1.9.4"
},
"devDependencies": {
"@types/leaflet": "1.9.4"
}
}

Ahora os explico paso a paso lo que debemos de especificar en cada apartado, para poder saber que debemos de añadir en cada uno de los puntos que se está observando.

  • description: Breve texto que explica su funcionalidad dentro de Qwik, sin apenas detalles.
  • dependencies: Se añaden las referencias a las dependencias NPM que se consideran de producción como en este caso leaflet, cuya versión actual será la 1.9.4.
  • devDependencies: Se añaden las referencias a las dependencias NPM que se consideran de desarrollo como en este caso @types/leaflet, cuya versión actual será 1.9.4.
  • __qwik__: Propiedad especial donde se almacenan datos importantes como el nombre que se visualizará en Qwik, prioridad, los enlaces de referencias a las documentaciones relacionadas que asignaremos en docs junto con nextSteps para especificar mediante lines información adicional de lo que podemos hacer después de integrar en nuestro proyecto Qwik.

Con esto, ya tenemos lo indispensable para poder seguir hacia adelante. Lo que vamos a conseguir en el primer paso es que nos notifiquen que dependencias se van a instalar al querer integrar esta funcionalidad.

Podríamos dejarlo en este punto y ya está, pero por facilitar las cosas (es super recomendable) vamos a añadir algunos ficheros que nos servirán como base para mostrar un ejemplo básico.

Creando ejemplo básico en funcionamiento

Lo que vamos a hacer es añadir el contenido que se visualizaría accediendo a una ruta. En este caso, mostraremos una ruta llamada /basic-map que mostrará un mapa a pantalla completa.

¿Es difícil hacerlo? ¿Cómo podemos hacerlo?

Ya conocemos como funciona lo que es la estructura de un proyecto Qwik, como se especifican las rutas (src/routes) y como los componentes (src/components) por ejemplo.

Basándonos en lo siguiente, añadimos dentro de un directorio src (en starters/features/leaflet-map) la siguiente estructura de ficheros y directorios.

El contenido de este directorio starters/features/leaflet/src se copiará directamente en src del nuevo proyecto al que integremos esta funcionalidad.

A tener en cuenta

Recordad que esto funcionaría como un proyecto Qwik y por ello, tendremos opción de añadir nuevas rutas, interfaces, datos, etc. Todo lo que necesitemos.

La estructura actual de esta nueva integración es la siguiente dentro de starters/features/leaflet-map:

...
leaflet-map
├── src
| ├── components
| | └── leaflet-map
| | └── index.tsx
| ├── models
| | ├── map.ts
| | └── location.ts
| ├── helpers
| | └── boundary-box.tsx
| └── routes
| └── basic-map
| └── index.tsx
└── package.json

Implementamos el código para especificar la plantilla del siguiente enlace teniendo en cuenta la estructura propuesta.

Lo que hay que tener en cuenta es cuando en los nombres de los ficheros del Gist aparece “_” quiere decir “/” en la ruta, lo demás es tal cual se ha especificado en la estructura.

Fijaros en los nombres y su ruta en los comentarios para añadirlo correctamente y seguir el proceso de estos pasos mediante este Gist:

https://shorten-up.vercel.app/ulQDjtqzJn

Una vez añadido el código (después de haberlo probado en otra app tal cual y ver que funciona todo OK) vamos a dar los pasos para probar la integración en local.

Probando la funcionalidad

Una vez que ya hemos implementado el código que queremos que tenga nuestra funcionalidad para integrarla en los proyectos de Qwik, debemos de seguir estos sencillos pasos.

  1. Compilar el proyecto al completo: pnpm build.full que se implementa tal y como se puede observar:

Y a continuación se muestran los pasos del proceso que irá dando, para que os hagáis una idea:

  • Empaquetando los ficheros de Qwik:
  • Va compilando las aplicaciones internas:
  • Generando la documentación:
  • Final del proceso (puede tardar unos minutos, la primera vez bastante más, paciencia):

2. Dentro del proyecto qwik (donde estamos trabajando) ejecutamos el siguiente comando:

pnpm link.dist

¿Que conseguiremos con esto?

Vamos a crear un enlace simbólico y dicho enlace habilita que haga una referencia local a este paquete completo que hemos compilado en desarrollo.

3. Con ello, podremos usarlo en cualquier apartado de nuestra máquina siempre y cuando hagamos referencia al paquete (o paquetes) que queremos consumir mediante pnpm link --global <paquete a enlazar>, que en este caso serán @builder.io/qwik y @builder.io/qwik-city.

Ahora lo que necesitamos es crear OTRO proyecto (como siempre), por ejemplo llamado qwik-integrate-maps-app.

Cuando lo tengamos, accedemos a el (tened cuidado aquí y aseguraros que estáis en el nuevo proyecto) mediante consola y ejecutamos:

pnpm link --global @builder.io/qwik @builder.io/qwik-city

Y al ejecutar el comando, ahí se ve como se actualiza el estado de las dependencias, integrando la referencia de los paquetes compilados anteriormente mediante el enlace simbólico:

Aquí lo que hace es ignorar los paquetes mencionados que están instalados en el proyecto de manera local (1) para usar los elementos que están enlazados simbólicamente que son ficheros binarios (2) con los cambios realizados con la nueva integración que estamos implementando:

4. Ejecutamos el comando para mostrar la lista de integraciones:

npm run qwik add

Y lo que se debería de ver es lo siguiente, donde se puede observar el texto asociado a la integración que acabamos de crear. Se visualiza el texto especificado en el texto (displayName) dentro de __qwik__ que se encuentra en el fichero package.json cuyo contenido es: Integration: Leaflet Maps.

Como se puede observar, en el momento que pones el foco sobre la opción de nuestra integración, se muestra la información adicional que corresponde al campo description del package.json.

Si seleccionamos la opción que corresponde a la integración de la que estamos hablando, mostrará la siguiente información donde nos especifica que va a realizar, a falta de confirmación:

Tip a tener en cuenta con las integraciones

Este paso (el de seleccionar desde una lista) lo podemos evitar si ya sabemos como ejecutar la integración, es decir, para leaflet-map tenemos la carpeta leaflet-map por lo que si queremos pasar ya directamente al último paso, debemos de ejecutar:
npm run qwik add leaflet-map

Seleccionando Yes looks good, finish update! ejecutamos la acción para integrarlo.

Cuando finalice y esté todo OK, nos dice que ya está OK y después nos muestra un apartado Action Required! que corresponde al texto que hemos indicado en el package.json en el apartado nextSteps y dentro de el, en el array asociado a lines donde se indica una información que puede resultar útil y/o necesaria para realizar ciertas acciones manuales:

5. Ejecutamos en este nuevo proyecto para iniciar con npm start y al iniciar, nos dirigimos a http://localhost:5173/basic-map/ cuyo contenido que se visualizará será el siguiente:

Y con esto, podemos dar por finalizada la prueba de esta integración.

Documentación de la integración

Ahora lo que nos hace falta es crear el apartado de documentación correspondiente de como funciona y que cosas hay que tener en cuenta para su uso.

ES MUY IMPORTANTE junto con la integración ya que todo va de la mano, la funcionalidad y su documentación, para que sea aceptada.

La documentación de estas integraciones la podemos encontrar en packages\docs\src\routes\docs\integrations (en el proyecto donde estamos contribuyendo).

Lo que vamos a hacer es crear un nuevo directorio llamado leaflet-map dentro de este apartado junto con un fichero index.mdx.

En el momento que se publique tanto la funcionalidad como la documentación, para acceder a la información de la documentación lo haremos mediante:

https://qwik.builder.io/docs/integrations/<carpeta-de-nueva-integracion>

En nuestro caso, como hemos añadido el directorio leaflet-map la URL será https://qwik.builder.io/docs/integrations/leaflet-map (aunque os esté enseñando esto en desarrollo, esto ya lo tenemos publicado)

Añadimos el contenido que queremos que se muestre en la documentación (basaros en otras opciones y adaptarlo a lo que estáis implementando):

---
title: LeafletJS Map | Integrations
keywords: 'map, interactive maps'
contributors:
- mugan86
---

# LeafletJS Map
Leaflet is the leading open-source JavaScript library for mobile-friendly interactive maps.
Weighing just about 42 KB of JS, it has all the mapping features most developers ever need.
.... (Especificamos todo lo necesario con todos los detalles)
## Usage
You can add LeafletJS Map easily by using the following Qwik starter script:
`npm run qwik add leaflet-map`
...

Para probar la documentación y verla en local, debemos de navegar dentro del proyecto qwik a packages\docs y una vez que hemos navegado, iniciamos el proyecto en local con pnpm start:

Automáticamente se nos abre la portada de la web principal de qwik (aunque en local, solo con fijarnos en la URL se puede ver):

Escribimos la url que se ha especificado antes para la integración adaptada a local:

http://localhost:3000/docs/integrations/leaflet-map/

Y al acceder, se puede observar todo lo que hemos especificado en la documentación:

Y ahora que ya hemos comprobado que el contenido se visualiza correctamente, el último paso consiste en añadir el enlace a la documentación de nuestro adaptador desde el menú y desde la lista de integraciones cuyo resultado debería de ser el siguiente:

Para implementar lo siguiente, accedemos a packages/docs/src/routes/docs/menu.md y debemos de añadir la referencia correspondiente a la integración de Leaflet Map que será integrations/leaflet-map/index.mdx ya que la ruta parte desde docs y debemos de añadir lo siguiente.

Procurad añadirlo en orden alfabético, siguiendo el orden que ya está establecido en la propia documentación. Pasamos de lo siguiente, donde no se encuentra Leaflet Map dentro de Integrations:

# Qwik Guide
....
## Integrations

- [Overview](integrations/index.mdx)
...
- [Tauri](integrations/tauri/index.mdx)
- [Turso](integrations/turso/index.mdx)
- [Vitest](integrations/vitest/index.mdx)
...
...

A lo siguiente, donde añadimos el contenido - [Leaflet Map](integrations/leaflet-map/index.mdx) dentro del apartado Integrations:

# Qwik Guide
....
## Integrations

- [Overview](integrations/index.mdx)
..
- [Leaflet Map](integrations/leaflet-map/index.mdx)
...
- [Tauri](integrations/tauri/index.mdx)
- [Turso](integrations/turso/index.mdx)
- [Vitest](integrations/vitest/index.mdx)
...

Si refrescamos ahora los cambios, en la documentación podremos ver que ya se ha añadido todo correctamente.

  • Lista de integraciones y menú lateral:
  • Seleccionado Leaflet Map:

Realizaremos los cambios y correcciones necesarios y con ello ya estaremos en posición de sugerir este conjunto como cambio mediante un Pull Request.

Preparativos previos al Pull Request

Antes de subir los cambios para abrir un Pull Request con la nueva integración (funcionalidad + documentación), debemos de tener en cuenta algunos aspectos.

Debemos de comprobar que el código pasa todo los estándares y una vez que pasa, lo empaquetamos, para que pueda pasar las verificaciones de CI (Integración continua) y todas las etapas que se especifican:

pnpm prettier.fix && pnpm syncpack format

Cuyo comando que está configurado, será:

pnpm fmt

Empezará el proceso:

Y durante un instante, hará todo el proceso, hasta llegar aquí:

Con esto ya hemos dado el último paso antes de guardar los cambios y dar el paso a sugerir el Pull Request de esta funcionalidad.

Ejecutamos:

git add --all && git commit -m "feat(integration): add new adapter to use leaflet map" && git push origin feature/leaflet-map-integration-adapter

Y una vez subidos los cambios, tendremos todos los cambios realizados en el siguiente enlace:

https://github.com/qwik-book/qwik/tree/feature/leaflet-map-integration-adapter

Crear Pull Request (PR) para integrarlo al framework

Una vez subidos los cambios, vamos a crear el Pull Request correspondiente a la integración que acabamos de crear y que queremos que forme parte de una de las funcionalidades del Framework.

Para crear el PR vamos al repositorio donde hemos hecho los cambios y seleccionamos Pull requests:

Y dentro de ese apartado New pull request (aparece la opción de hacerlo directamente pero imaginaros que no lo hace):

Ahora observamos un apartado donde se hace la comparativa de las ramas.

A la derecha tenemos nuestro repositorio (el que es la copia del original) junto con la rama que será la que vamos a integrar en el repositorio oficial de Qwik en la rama main.

Seleccionamos la opción de Create pull request

Se abrirá un formulario donde tenemos que añadir un título, que tendrá que seguir las buenas prácticas de commits.

Aplicar buenas prácticas en los commits

Cosas a tener en cuenta para aplicar buenas prácticas para escribir mensajes de commit y como en este caso es una funcionalidad nueva, añadimos como valor inicial feat y posteriormente especificamos una descripción corta y clara como new integrate with leaflet maps quedando lo siguiente:

feat: new integrate with leaflet maps

Cambiamos el título:

Y añadimos el contenido de la descripción:

# Overview

# What is it?
- [X] Feature / enhancement
- [ ] Bug
- [ ] Docs / tests / types / typos

# Description

In this functionality I want to facilitate the process to start working with Maps in Qwik using the LeafletJS Map library, which will be used to carry out projects like the following example:
https://qwik-osm-poc.netlify.app/
A basic map has been added with some simple functions such as adding a marker with a popup in a specific location leaving it open to many improvements, such as dynamic resizing, dynamic id to put more than one map per page, adding plugins,... .
For this, I have added main information of the LeafletJS API regarding the official documentation and example tutorials to learn interesting things.
To execute this integration, we must have the project prepared and the latest changes compiled
Complete Compilation:
`pnpm build.full`
Create the symbolic link with the news:
`pnpm link.dist`
And creating a new Qwik project we install those dependencies of what we just added, to be able to run the script with `npm run qwik add` to show the entire list or directly execute the proposed integration with `npm run qwik add leaflet- map`.
When executed, we will have the following:
![image](https://github.com/BuilderIO/qwik/assets/105705996/c5ffb473-a31e-4413-8b6d-79dc49e5609d)
And once integrated, if we start the project and access the /basic-map route we can see a full screen map like the following one, which will be available to make changes such as zoom, location (it is currently located in my town, north of Spain),...
![image](https://github.com/BuilderIO/qwik/assets/105705996/7df04d53-2eb0-489d-a434-b6c718a7e3e1)

# Use cases and why
<!-- Actual / expected behavior if it's a bug -->
- 1. One use case
- 2. Another use case

# Checklist:
- [X] My code follows the [developer guidelines of this project](https://github.com/BuilderIO/qwik/blob/main/CONTRIBUTING.md)
- [X] I have performed a self-review of my own code
- [X] I have made corresponding changes to the documentation
- [ ] Added new tests to cover the fix / functionality

Siendo este el resultado:

Para enviar la solicitud del PR seleccionamos Create pull request y se verá de la siguiente forma (actualmente ya está aprobado y mergeado y lo podéis ver en este enlace):

Ahora llega el momento que ya nos harán la revisión, nos sugerirán cambios y tenemos que estar abiertos a ello, ya que la primera vez que se hace algo así en un proyecto que no conocemos al detalle, habrán muchos aspectos pequeños que se nos escapen y tendremos que ir poco a poco mejorando y afinando.

Si llega el momento que se nos aprueba, aparecerá con la etiqueta Merged:

Y ya aparecerá como cerrado el Pull Request:

Ahora solo quedará a que se añada en la próxima versión, ¡¡paciencia!!

¿Qué hemos aprendido en este artículo?

Al finalizar este artículo, deberíamos de ser capaces de:

  • Entender que es una integración y como podemos usarlas para nuestro beneficio.
  • Entender los pasos a dar para crear una nueva funcionalidad con una integración que proponemos paso a paso.

Conclusion

Los integraciones son un aspecto muy interesante en Qwik que nos va a permitir arrancar proyectos con funcionalidades comunes de manera rápida y limpia, olvidando los pasos “pesados” y engorrosos que suelen ser un montón de veces.

Os animo que trabajéis con los disponibles y que también aportéis los vuestros, de alguna que otra funcionalidad que actualmente no existe y creáis que puede ser útil para la comunidad, aportando vuestro granito de arena.

Libro de Qwik

Este es un capítulo completo del libro titulado Dominando Qwik desde 0 a producción que estará a la venta próximamente que constará de 23 capítulos, desde las bases hasta la producción.

Espero vuestro apoyo, ya que es un proyecto en el que he trabajado durante un año y he añadido cosas tan interesantes como lo de este capítulo entre otras muchas que encontraréis.

Presencia en redes sociales

Podéis encontrarme en las siguientes redes.

--

--

Anartz Mugika Ledo🤗
Anartz Mugika Ledo🤗

Written by Anartz Mugika Ledo🤗

[{#frontend:[#mobile:{#android, #kotlin, #ionic}}, {#web:{#angular, #qwik, #bootstrap}}],{#backend: [{#graphql, #nestjs,#express, #mongodb, #mysql}]}]

No responses yet