<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jakub Przyborowski</title>
    <description>The latest articles on DEV Community by Jakub Przyborowski (@przyb).</description>
    <link>https://dev.to/przyb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F347407%2Fffb7d7ab-1155-4cd9-be36-7f946d5799c5.jpeg</url>
      <title>DEV Community: Jakub Przyborowski</title>
      <link>https://dev.to/przyb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/przyb"/>
    <language>en</language>
    <item>
      <title>​​Using Vue without actually using Vue. Ovee.js 2.1 just got released.</title>
      <dc:creator>Jakub Przyborowski</dc:creator>
      <pubDate>Wed, 03 Nov 2021 17:52:29 +0000</pubDate>
      <link>https://dev.to/owlsdepartment/using-vue-without-actually-using-vue-oveejs-21-just-got-released-365o</link>
      <guid>https://dev.to/owlsdepartment/using-vue-without-actually-using-vue-oveejs-21-just-got-released-365o</guid>
      <description>&lt;p&gt;When we first started drafting the idea for &lt;a href="https://owlsdepartment.github.io/ovee/"&gt;Ovee.js&lt;/a&gt; (check out &lt;a href="https://github.com/owlsdepartment/ovee"&gt;the repo on GitHub&lt;/a&gt; and leave a star 🙏), we’ve decided that we don’t want to reinvent the wheel and wanted to avoid reimplementing complex parts like reactivity or templating for the millionth time. It’s a popular principle among back-end frameworks - Laravel heavily reuses parts of Symfony, Symfony by default comes bundled with Doctrine, Nest depends on Express (which even can be replaced with other implementation on demand). Yet, in the front-end field, each of the big frameworks is built fully independently (correct me, if I’ve missed something). &lt;/p&gt;

&lt;p&gt;For the initial build of Ovee.js, we’ve chosen &lt;a href="https://github.com/sindresorhus/on-change"&gt;on-change&lt;/a&gt; for handling simple reactivity, and &lt;a href="https://github.com/lit/lit/tree/main/packages/lit-html"&gt;lit-html&lt;/a&gt; for templating. We’ve also built an optional module on top of &lt;a href="https://github.com/barbajs/barba"&gt;Barba&lt;/a&gt; for asynchronous page transitions. This decision helped us to ship the first working version of the framework relatively fast, avoiding major bugs in the potentially most complex parts.&lt;/p&gt;

&lt;p&gt;Since the release of Vue 3, we started to tinker with its internals and decided to eventually replace on-change with a much more capable solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  More power with Vue 3 modules
&lt;/h2&gt;

&lt;p&gt;Vue 3 brought great, well-received changes to its API. But from our point of view, we also got two really important changes, that might get overlooked by most developers. &lt;/p&gt;

&lt;p&gt;First thing is that the reactivity got rewritten to Proxy API, which solves the constraints of the previous implementation, and is much more clean and modern. For Ovee.js, we intended to use Proxy API from the very beginning, which is why we couldn’t rely on Vue 2 reactivity for the initial build. &lt;/p&gt;

&lt;p&gt;Second, an even more important change is that Vue is now shipped in modular form, and parts of the framework are available as separate NPM packages. This way, we can use &lt;code&gt;@vue/reactivity&lt;/code&gt; without having the whole framework as a dependency. And when it comes to the number of dependencies, a smaller footprint means faster installation and a smaller &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The experience of using independent parts of Vue 3
&lt;/h2&gt;

&lt;p&gt;As we intended to only replace the Ovee’s reactivity, we’ve added &lt;code&gt;@vue/reactivity&lt;/code&gt; and &lt;code&gt;@vue/runtime-core&lt;/code&gt; to our dependency tree. The first one, just as the name suggests, gave us tools to rebuild our &lt;code&gt;ReactiveProxy&lt;/code&gt; class. Usage is super easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue/reactivity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The latter brings &lt;code&gt;watch&lt;/code&gt;, &lt;code&gt;computed&lt;/code&gt;, and &lt;code&gt;watchEffect&lt;/code&gt;. Earlier, we had &lt;code&gt;@watch&lt;/code&gt; decorator, but with our own implementation. Now, we could just use &lt;code&gt;watch&lt;/code&gt; from &lt;code&gt;@vue/runtime-core&lt;/code&gt; package. Going further, we added 2 new decorators: &lt;code&gt;@watchEffect&lt;/code&gt; and &lt;code&gt;@computed&lt;/code&gt;, which just wrap their respective methods.&lt;/p&gt;

&lt;p&gt;But that’s not everything! The &lt;code&gt;TemplateComponent&lt;/code&gt; from Ovee.js also relyed on watch and reactivity system, to automatically re-render lit templates when any of the reactive data changes. We replaced it with helpful &lt;code&gt;watchEffect&lt;/code&gt; underneath, which ultimately reduced lines of code and simplified how the system worked.&lt;/p&gt;

&lt;p&gt;Currently, we only replaced the old reactivity system and added a few wrappers. But Vue reactivity system is so versatile, we can build a lot of cool new features as part of the core package and new modules as well! Of course, the same benefits are now available to the developers using Ovee.js.&lt;/p&gt;

&lt;p&gt;Overall, the whole Vue reactivity system is well documented and easy to use. It is also written in TypeScript, with very good typings, which is also a big con for us, as we use TypeScript as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, so what’s that Ovee.js thing?
&lt;/h2&gt;

&lt;p&gt;Ovee.js is a component framework designed to work with server-side rendered markup. It means that it is not a competition for Vue or React, but rather a modern approach for projects, where we would use jQuery in the past. You can read more about Ovee.js &lt;a href="https://owlsdepartment.com/blog/introducing-oveejs-framework/"&gt;here&lt;/a&gt; and take a peek at &lt;a href="https://owlsdepartment.github.io/ovee/"&gt;the official documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Create tidy front-end components for server-side rendered markup - introducing Ovee.js framework.</title>
      <dc:creator>Jakub Przyborowski</dc:creator>
      <pubDate>Wed, 25 Aug 2021 15:57:59 +0000</pubDate>
      <link>https://dev.to/owlsdepartment/create-tidy-front-end-components-for-server-side-rendered-markup-introducing-ovee-js-framework-2kem</link>
      <guid>https://dev.to/owlsdepartment/create-tidy-front-end-components-for-server-side-rendered-markup-introducing-ovee-js-framework-2kem</guid>
      <description>&lt;p&gt;I remember, when I first discovered jQuery. It was around 2009 and I was a junior back-end developer, who loved also CSS but hated didn’t understand JS. I was amazed, that suddenly I had a tool, that let me create front-end interactions without much struggle. For the next few years, I became a full-stack dev and loved to have jQuery at my side. Yet, there was one thing I really missed from my back-end garden: the structure that MVC frameworks gave me. You know, out of larger organizations, there was no front-end architecture in most projects that were made in the late 2000s and early 2010s. Just a bunch of random event handlers put into a single functions.js file. Maybe, but just maybe, some prototype-based classes, if you were fancy.&lt;/p&gt;

&lt;p&gt;To be honest, this style of doing JS still resonates in the works of many devs even today, if they are working on a simple website, not an enterprise-level app. I don’t wanna hate, I wanna help - but let’s continue with the story for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  In search of a good front-end architecture for non-application projects
&lt;/h2&gt;

&lt;p&gt;In search for better front-end architecture, around 2011-2013 I got fascinated by Backbone, then Angular.js. These frameworks were cool for building SPAs, but no one but some hipsters used them to build websites, as achieving SSR was a huge struggle. And you still wanted your site to be indexable by search engines.&lt;/p&gt;

&lt;p&gt;In the meantime, when building websites, I’ve started to structure my JS into a pile of objects with simple auto-initialization magic. Still jQuery, still no build tools (other than some minification maybe). Sucked a little less, but still meh.&lt;/p&gt;

&lt;h2&gt;
  
  
  There’s a life beyond everything-in-js
&lt;/h2&gt;

&lt;p&gt;With the rise of React and Vue, things got fancy. We now have static generators like Gatsby, Next.js, Nuxt.js, Gridsome, and dozens of others. And with them, the problem with SSR disappeared. But, have you tried to build a marketing-focused website on top of any of these? Yes, these are great tools and have many advantages, but the development cost can be 2-3 times higher, and you lose the simplicity of the “classic” sites built as templates for one of popular CMS systems. &lt;/p&gt;

&lt;p&gt;With my team at Owls Department, we try to value picking the right tools for the job over following the lead of hype and fanciness. I really, really love Vue and evangelize it to my clients, when we pitch for application projects. Yet, when it comes to most website builds, we go “classic”. I believe there’s a place for using different approaches when seeking a successful front-end product - take a look at Signal’s Basecamp or GitLab - these are both mostly server-side rendered products and using them feels nice and smooth to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Look mum, I’ve built another JS framework
&lt;/h2&gt;

&lt;p&gt;Over the years, I’ve searched for a good solution to keep the JS that we build for server-side rendered markup up to the same coding and architectural standards that we use when building SPAs with Vue. And didn’t find a good one, so started to DIY something for my team. The first version of our internal framework was built around the idea of a component, that hooks to matching structure in html (selected by &lt;code&gt;data-&lt;/code&gt; parameter - inspired by good ol’ Angular v1) and encapsulates the JS magic. It still used jQuery here and there. But it freakin’ worked. We were able to build quite complex sites, while keeping the code maintainable. We were able to reuse components, so the work was done faster.&lt;/p&gt;

&lt;p&gt;In late 2019 I had a chat with some team members, that it would be good to finally ditch the jQuery and also switch from our proprietary pjax clone to Barba for page transitions. When doing my research, I found Basecamp’s Stimulus (&lt;a href="https://stimulus.hotwired.dev/"&gt;https://stimulus.hotwired.dev/&lt;/a&gt;) - now part of Hotwire suite. I love the work of these guys, but I don’t like how much JS-related stuff (e.g. binding events) is done in the server-side rendered markup. There’s also Strudel.js (&lt;a href="https://strudel.js.org/"&gt;https://strudel.js.org/&lt;/a&gt;), which comes from a similar background to ours. When I started to modernize our framework, I’ve found a lot of inspiration in Strudel’s design and API (kudos to the team behind this pastry-flavored framework). &lt;/p&gt;

&lt;p&gt;By the mid of 2020, we had the new framework ready to use internally. We’ve decided to publish it as open-source under MIT license, and named it Ovee.js. It’s fully written in TypeScript (huge contribution from @F0rsaken), has good unit test coverage, and is here to help teams and individuals, who struggle with problems similar to ours. Now it’s ready for you to discover it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Show me the code
&lt;/h2&gt;

&lt;p&gt;Let’s take a quick journey, so you could feel how the framework tastes.&lt;/p&gt;

&lt;p&gt;Installation is nothing special:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add ovee.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A component is a building block of your website or an application. In Ovee.js, it is represented by a class and corresponding markup. The framework detects html tag matching the component by either tag name or a data parameter. Each instance of matched tag gets its own instance of the component class.&lt;/p&gt;

&lt;p&gt;Let's take a look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;incremental-counter&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"incremental-counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"incremental-counter__value"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"incremental-counter__button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;increment!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/incremental-counter&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;watch&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ovee.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incremental-counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.incremental-counter__value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;valueElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.incremental-counter__button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;immediate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Current value: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, within the component class we can reference children elements that are contained within its corresponding DOM node. The framework gives us convenient mechanisms to bind events, DOM elements and react to data changes.&lt;/p&gt;

&lt;p&gt;The framework is reactive if you want it to be reactive. It uses the power of MutationObserver, so you don’t need to manually initialize or destroy components when you modify the DOM (e.g. by changing views using Barba). &lt;/p&gt;

&lt;p&gt;The initialization is pretty straightforward, and if you ever used any modern framework, you’ll see the similarities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ovee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OveeBarba&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ovee.js/barba&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;IncrementalCounter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/IncrementalCounter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nx"&gt;IncrementalCounter&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nx"&gt;OveeBarba&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, and you remember when I told you that it’s meant to work only with server-side generated markup? Oh, I kinda lied. You see, that’s the core use case. But sometimes a project that in 90% fits the use case for rendering markup on the back-end, this one pretty dynamic part. And when you think about how to approach it, this part shouts “duude, React or Vue would serve me well”. For such scenarios, we’ve extended the default Component’s design with the power of Polymer’s lit-html. So, some of your components can be client-side rendered, if you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;TemplateComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;register&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ovee.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incremental-counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;TemplateComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.incremental-counter__button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="s2"&gt;`
            &amp;lt;p class="incremental-counter__value"&amp;gt;Current value: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
            &amp;lt;button class="incremental-counter__button"&amp;gt;increment!&amp;lt;/button&amp;gt;
        `&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neat, right? This way it’s your decision, how you build your stuff. Not the framework’s. &lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;Our team at Owls Department uses the thing daily. We collect the team’s feature requests and have plans for the future development of the framework. The biggest change we have in mind is adapting Vue 3’s reactivity in place of the solution we have in place. With this change, we are looking forward to performance gains, especially when it comes to &lt;code&gt;TemplateComponent&lt;/code&gt;. If you have any ideas or want to contribute, give us a heads up!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reads
&lt;/h2&gt;

&lt;p&gt;I hope you’ll find the project interesting and I’ve convinced you to try Ovee.js. &lt;/p&gt;

&lt;p&gt;In the future, I’ll cover Ovee’s features in more in-depth articles. Please, follow us on Twitter (&lt;a href="https://twitter.com/owlsdepartment"&gt;@owlsdepartment&lt;/a&gt;), Dev.to (&lt;a href="https://dev.to/owlsdepartment/"&gt;@owlsdepartment&lt;/a&gt;) and Instagram (&lt;a href="https://instagram.com/owlsdepartment/"&gt;@owlsdepartment&lt;/a&gt;), so you don’t miss any future publications.&lt;/p&gt;

&lt;p&gt;The full documentation can be found here: &lt;a href="https://owlsdepartment.github.io/ovee/"&gt;https://owlsdepartment.github.io/ovee/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the library is still fresh, the community is still to come. But, what is important - our team is using Ovee.js on daily basis, so we are commited to maintain and improve it in future. If you have any questions or ideas, don’t hesitate to catch us via Twitter (&lt;a href="https://twitter.com/owlsdepartment"&gt;@owlsdepartment&lt;/a&gt;) or through &lt;a href="https://github.com/owlsdepartment/ovee/issues"&gt;GitHub Issues&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>oveejs</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>​​We made a mobile game with Godot. Here’s what we've learned.</title>
      <dc:creator>Jakub Przyborowski</dc:creator>
      <pubDate>Sat, 26 Dec 2020 12:48:31 +0000</pubDate>
      <link>https://dev.to/owlsdepartment/we-made-a-mobile-game-with-godot-here-s-what-we-ve-learned-2942</link>
      <guid>https://dev.to/owlsdepartment/we-made-a-mobile-game-with-godot-here-s-what-we-ve-learned-2942</guid>
      <description>&lt;p&gt;Some time ago, our team built a mobile game. But first things first. Let’s start with a short disclaimer - we are mainly web developers. We love to tinker with different technologies, and some of us had some experience with Unreal Engine, Unity, Phaser or even Flash in good ol’ days. Yet, we’re not specialized in game dev - that’s a fact, nothing to be embarrassed and we think an important acknowledgement for the rest of this article. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; this article was based on our experience with Godot in versions 3.2.2/3.2.3. Since then, new versions might have been published, and some of the mentioned issues might be now solved.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The subject
&lt;/h1&gt;

&lt;p&gt;We got commissioned to build a mobile game for an NGO. It had to be educational, yet we really wanted to keep it playful and engaging for a casual player. Our creative team came up with an idea of an illustrated 2d platform game, interspersed with educational quizzes from time to time. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why we’ve picked Godot
&lt;/h1&gt;

&lt;p&gt;As our design team decided to go with an illustrational style, we knew that we’ll be working mostly with animated sprites. The gameplay quality was really important for us, so we knew we want to use an existing engine, rather than reinvent the wheel. We thought about Unity for a brief moment, but we don’t love how it works with version control, as scenes are saved in binary format. We also prefer to pick open source projects when possible. If you google for such engine, you’ll probably find Godot, Defold and some 2d-only engines.&lt;/p&gt;

&lt;p&gt;We wanted to pick something universal, that could benefit us also in 3d game dev in future. Defold seems nice, but at the time of our decision, it seemed much less mature and popular (1.2k stars on GitHub, vs 35k for Godot). Also one of the team members had already played with Godot a little bit, so we went with his recommendation.&lt;/p&gt;

&lt;h1&gt;
  
  
  The language
&lt;/h1&gt;

&lt;p&gt;While many competitors in the area of open-source game engines rely on Lua, Godot brings its very own GDScript language. It also brings support for C++ and C# on top of Mono. Yet, GDScript seems like the best option as it deeply integrates with the engine so most times code for the same functionality will be much simpler in GDScript. Also, most of the materials you’ll find over the Internet is based on GDScript. So, as long as you’re not a daily C++ or C# developer, you should probably pick GDScript. And that’s what we did.&lt;/p&gt;

&lt;p&gt;GDScript is a python-influenced language, created with a single purpose. In our experience, it’s easy to learn. If you casually use Python, you’ll feel most at home. Honestly, it felt easy to start using even for a person who hasn’t used Python for like 10 years. &lt;/p&gt;

&lt;p&gt;We really liked the integration with the engine. It brings easy to use event system, that was good enough for most of our cases. The option of writing semi-async parts of code with yield is really helpful. Yet, there are also disadvantages of being a single-purpose and not widely used language. It lacks the idea of private fields or methods, so you end up with an underscore-prefixed mess. Instantiating object is inconsistent - for scripts you call &lt;code&gt;new()&lt;/code&gt;, yet for scenes, you call &lt;code&gt;instance()&lt;/code&gt;. What’s worse, you can instantiate a script instead of a scene by mistake if you name it with &lt;code&gt;class_name&lt;/code&gt; or load &lt;code&gt;.gd&lt;/code&gt; instead of &lt;code&gt;.tscn&lt;/code&gt; file and you won’t get any clue from the engine or editor other than meaningless runtime errors. Also, a clean way of importing classes/scripts together with a proper package manager would make it less like it’s 2003 and you’re still rockin’ PHP3. Yet, if you learn to live with those disadvantages, it does its job and you’ll find it okay.&lt;/p&gt;

&lt;p&gt;GDScript also comes with optional Types. The notation is similar to Python’s typing, but you can only use native types along with classes, that you can access either by making them global with &lt;code&gt;class_name&lt;/code&gt; keyword or loading using &lt;code&gt;const … = preload('…')&lt;/code&gt;. No generics, interfaces and other things that you expect to find in a strongly typed language. Yet we still appreciated the existing support and used it as much as possible.&lt;/p&gt;

&lt;p&gt;But things are changing and GDScript will get its next iteration with Godot 4, which looks very promising, to be honest.&lt;/p&gt;

&lt;h1&gt;
  
  
  The editor
&lt;/h1&gt;

&lt;p&gt;Godot as a fully blown game engine comes with its very own editor for both visual stuff and scripting. What’s impressive is that the editor itself is fully written in Godot. Works okay and has a lot of helpful features, including animation editor (if you ever used Flash, you’ll feel the nostalgia), visual editor for scenes and UI and easy way to bind signals (events) with your scripts. It also has built-in documentation, which is a nice bonus. &lt;/p&gt;

&lt;p&gt;On the other hand, we sometimes felt it tries too hard to do everything within the engine. For example, things that in most programs are using OS controls like file open/save dialogues, here are also custom-built. Maybe we wouldn’t mind if the experience was similar to the native one, but using it is dreadful and we’d really appreciate native controls here instead.&lt;/p&gt;

&lt;p&gt;For writing scripts, you can use an external editor (there are third party packages with syntax support for VSCode, Atom and Sublime). But that, at least for VSCode, requires the official editor to be open in the background anyway.&lt;/p&gt;

&lt;h1&gt;
  
  
  Building the gameplay
&lt;/h1&gt;

&lt;p&gt;Godot goes really well with 2D games and the amount of built-in tools and solutions is huge. We rarely had a problem, that a tool or helper was missing.&lt;/p&gt;

&lt;p&gt;Games in Godot are built with nodes. The ability to combine two totally different nodes, that the engine gives you, is amazing! Also, in our opinion, the documentation is very good, at least comparing to other game engines. Sometimes it lacks more explanation or examples, but overall it’s in a good state.&lt;/p&gt;

&lt;p&gt;But, unfortunately, nothing is perfect, and neither is Godot.&lt;/p&gt;

&lt;p&gt;We were struggling with ParallaxBackground, because of the different resolutions we had to handle. And as it turned out, there is a nasty bug, that occurs when you change your screen resolution (at least in versions 3.2.2/3.2.3 that we’ve used). There were also some weird quirks when it came to physics of the body, controlling it, repositioning and stuff like that.&lt;/p&gt;

&lt;p&gt;And yet, there were many things that we were very positively surprised with. To name a few - sprite animations, 2D transformations, global and local coordinates, collision handling and many other things. Prototyping, managing assets and level designing were a breeze. And at the end, we managed to (with some effort) get rid of (or around :)) all major bugs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Building the UI
&lt;/h1&gt;

&lt;p&gt;As even the Godot’s own editor is built on top of the engine, its support for building UIs is a first-class citizen. It brings you a catalogue of ready-made, stylable components that should do the job for most scenarios. The game we were building had quite a lot of UI for its size, as besides the core gameplay we also had to build functionalities like quizzes, educational tips, accomplishments lists, disclaimer screens and stuff like that.&lt;/p&gt;

&lt;p&gt;Godot provides us with two ways of styling components. You can either manually attach styles per each component (these can be saved into files and reused between multiple components), or you can define so-called themes. This way, you can style a component together with its children - kinda like with CSS, but with a visual editor. To be honest, we found using just reusable styles without whole themes thing more streamlined and easy enough to maintain for a project of our scale. &lt;/p&gt;

&lt;p&gt;What we found surprising and very unfortunate, was the total lack of touch support for scrollable containers. You should keep this in mind, that when implementing UI for mobile games, you’ll be required to code goodies like kinetic scrolling all by yourself. &lt;/p&gt;

&lt;p&gt;What you will find helpful, is that the engine brings us multiple ways for creating animations. Besides the mentioned visual animation editor, you can use built-in tweens. If you ever used TweenMax, you’ll know what to do. It lacks a true timeline for orchestrating animations from code, however in our case playing a little with delays and durations did the job. What’s missing is an option to provide a custom easing curve, so you need to relay on built-ins.&lt;/p&gt;

&lt;p&gt;One big, yet important hole in the ecosystem is the lack of any navigation management. So if you want to build some hierarchy between UI screens, together with animated transitions, you’ll once again be on your own. &lt;/p&gt;

&lt;p&gt;In terms of animations, you’d be able to build something modest pretty easily. However, if you’re about to create anything fancy, you’ll quickly end up messing with shaders. So what’s missing is something to fill the gap between super simple and super complex animation techniques. &lt;/p&gt;

&lt;h1&gt;
  
  
  Integration with native APIs
&lt;/h1&gt;

&lt;p&gt;TL;DR: if there’s an existing plugin, it’s easy. If not, you’re on your own.&lt;/p&gt;

&lt;p&gt;Our game was intended mostly for Android, and for this OS, there is a pretty good new plugin system, introduced with 3.2 version of Godot. It’s much more straightforward than the previous module system. Godot does not bring too many platform-specific integrations. If you want to integrate analytics, push notifications, social media integrations etc, you won’t find any of these stuff within the core so you’ll need to rely on plugins. That’s a reasonable idea as it allows Godot maintainers to focus on the engine’s core. &lt;/p&gt;

&lt;p&gt;At the time of writing this article, a lot of possibly useful plugins don’t exist yet, and if you find what you need it would probably be some alpha version with few stars on GitHub, poor documentation and not always working properly. We hope this to change in future, but if you plan to use Godot for your next project, do some research to avoid trouble in the middle of the job.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Overall, we’ve enjoyed working with Godot on the project. We’ve built a playful and enjoyable game and were able to rapidly prototype its mechanics at an early stage. However, due to limitations of the engine’s UI framework and lack of high-quality plugins for Android, we found it pretty challenging to develop a smooth experience around the core gameplay. &lt;/p&gt;

&lt;p&gt;Anyway, we deeply appreciate lots of hard work done by Godot’s maintainers and we’ll keep our fingers crossed for the engine’s future development.&lt;/p&gt;

&lt;p&gt;Thanks for reading! &lt;/p&gt;

&lt;p&gt;If you’re looking for a team of creative and passionate developers and product designers, don’t hesitate to visit our website at &lt;a href="https://www.owlsdepartment.com"&gt;https://www.owlsdepartment.com&lt;/a&gt; or email us at &lt;a href="mailto:hello@owlsdepartment.com"&gt;hello@owlsdepartment.com&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Authors: &lt;br&gt;
Kuba Przyborowski &lt;a href="https://github.com/przyb"&gt;@przyb&lt;/a&gt;&lt;br&gt;
Milosz Mandowski &lt;a href="https://github.com/F0rsaken"&gt;@F0rsaken&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>mobile</category>
      <category>godot</category>
      <category>gdscript</category>
    </item>
  </channel>
</rss>
