<?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: Copple</title>
    <description>The latest articles on DEV Community by Copple (@kiwicopple).</description>
    <link>https://dev.to/kiwicopple</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%2F220399%2F22d8e342-77f5-4408-a02f-d9432711645f.png</url>
      <title>DEV Community: Copple</title>
      <link>https://dev.to/kiwicopple</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kiwicopple"/>
    <language>en</language>
    <item>
      <title>pgvector 0.6.0: 30x faster with parallel index builds</title>
      <dc:creator>Copple</dc:creator>
      <pubDate>Wed, 31 Jan 2024 15:30:41 +0000</pubDate>
      <link>https://dev.to/supabase/pgvector-060-30x-faster-with-parallel-index-builds-i1l</link>
      <guid>https://dev.to/supabase/pgvector-060-30x-faster-with-parallel-index-builds-i1l</guid>
      <description>&lt;p&gt;pgvector 0.6.0 was released today, with a significant improvement: parallel builds for HNSW indexes. Building an HNSW index is now up to 30x faster for unlogged tables.&lt;/p&gt;

&lt;p&gt;This release is a huge step forward for pgvector, making it easier to tune HNSW build parameters and increase search accuracy and performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  HNSW indexes in pgvector
&lt;/h2&gt;

&lt;p&gt;We explored &lt;a href="https://supabase.com/blog/increase-performance-pgvector-hnsw#how-does-hnsw-work" rel="noopener noreferrer"&gt;how HNSW works&lt;/a&gt; in an earlier post, so as a quick recap: HNSW is an algorithm for approximate nearest neighbor search. It uses proximity graphs and consists of two parts: hierarchical and navigatable small world. It operates over multiple layers with different densities or distances between nodes, where layers represent different connection lengths between nodes. Thus allowing HNSW to search, insert, and delete in linearithmic time.&lt;/p&gt;

&lt;h2&gt;
  
  
  pgvector parallel index builds
&lt;/h2&gt;

&lt;p&gt;Prior to 0.6.0, pgvector only supported building indexes using a single thread - a big bottleneck for large datasets. For example, building an index for 1 million vectors of 1536 dimensions would take around 1 hour and 27 minutes (with &lt;code&gt;'m'=16, 'ef_construction'=200&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;With parallel index builds you can build an index for the same dataset in 9.5 minutes - 9 times faster:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsupabase.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Fblog%252F2024-01-30-pgvector-fast-builds%252Ffastbuilds-comparison--dark.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsupabase.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Fblog%252F2024-01-30-pgvector-fast-builds%252Ffastbuilds-comparison--dark.png%26w%3D3840%26q%3D75" alt="pgvector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance comparison: pgvector 0.5 vs 0.6
&lt;/h2&gt;

&lt;p&gt;We tested index build time with the &lt;a href="https://huggingface.co/datasets/KShivendu/dbpedia-entities-openai-1M" rel="noopener noreferrer"&gt;dbpedia-entities-openai-1M&lt;/a&gt; dataset (1 million vectors, 1536 dimensions) to compare the performance of parallel and single-threaded index HNSW builds. At the same time, we verified that the resulting indexes are the same in terms of accuracy and queries per second (QPS).&lt;/p&gt;

&lt;p&gt;We ran benchmarks on various database sizes to see the impact of parallel builds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4XL instance (16 cores 64GB RAM)&lt;/li&gt;
&lt;li&gt;16XL instance (64 cores 256GB RAM)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4XL instance (16 cores 64GB RAM)
&lt;/h3&gt;

&lt;p&gt;This benchmark used the following parameters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;0.5.1&lt;/th&gt;
&lt;th&gt;0.6.0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mainenance_work_mem&lt;/td&gt;
&lt;td&gt;30GB&lt;/td&gt;
&lt;td&gt;30GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_parallel_maintenance_workers&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;max_parallel_maintenance_workers&lt;/code&gt; controls how many parallel threads are used to build an index. In further sections we will refer to the total number of workers, including the leader.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsupabase.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Fblog%252F2024-01-30-pgvector-fast-builds%252Fbuild-params--dark.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsupabase.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Fblog%252F2024-01-30-pgvector-fast-builds%252Fbuild-params--dark.png%26w%3D3840%26q%3D75" alt="pgvector bench"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The index build time is 7-9 times faster for 0.6.0, while queries per second and accuracy stay the same for both versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;v0.5.1&lt;/code&gt;: averaged 938 QPS and 0.963 accuracy across all benchmarks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;v0.6.0&lt;/code&gt;: averaged 950 QPS and 0.963 accuracy across all benchmarks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  16XL instance (64 cores 256GB RAM)
&lt;/h3&gt;

&lt;p&gt;You can further improve index build performance using a more powerful instance (up to 13.5x for these parameters).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsupabase.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Fblog%252F2024-01-30-pgvector-fast-builds%252Ffastbuilds-comparison--dark.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsupabase.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Fblog%252F2024-01-30-pgvector-fast-builds%252Ffastbuilds-comparison--dark.png%26w%3D3840%26q%3D75" alt="bench 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The index build time is not linearly proportional to the number of cores used. A sensible default for &lt;code&gt;max_parallel_maintenance_workers&lt;/code&gt; is &lt;code&gt;CPU count / 2&lt;/code&gt; , the default we set on the Supabase platform. Accuracy and QPS are not affected by &lt;code&gt;max_parallel_maintenance_workers&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Embeddings with unlogged tables
&lt;/h3&gt;

&lt;p&gt;Building time can be reduced &lt;em&gt;even further&lt;/em&gt; using unlogged tables.&lt;/p&gt;

&lt;p&gt;An unlogged table in Postgres is a table whose modifications are not recorded in the write-ahead log (trading performance for data reliability). Unlogged tables are a great option for embeddings because the raw data is often stored separately and the embeddings can be recreated from the source data at any time.&lt;/p&gt;

&lt;p&gt;One of the steps of index creation is the final scan and WAL writing. This is generally short but not parallelizable. Using unlogged tables allows you to skip the WAL, with an impressive impact:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ef_construction&lt;/th&gt;
&lt;th&gt;Build time: v0.5.1&lt;/th&gt;
&lt;th&gt;Build time: v0.6.0 (unlogged)&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;38m 08s&lt;/td&gt;
&lt;td&gt;1m 38s&lt;/td&gt;
&lt;td&gt;23x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;1h 06m 59s&lt;/td&gt;
&lt;td&gt;2m 10s&lt;/td&gt;
&lt;td&gt;31x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;1h 27m 45s&lt;/td&gt;
&lt;td&gt;3m 37s&lt;/td&gt;
&lt;td&gt;24x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;pgvector 0.6.0 was &lt;a href="https://github.com/pgvector/pgvector/releases/tag/v0.6.0" rel="noopener noreferrer"&gt;just released&lt;/a&gt; and will be available on Supabase projects soon. Again, a special shout out to Andrew Kane and everyone else who &lt;a href="https://github.com/pgvector/pgvector/issues/409" rel="noopener noreferrer"&gt;worked on parallel index builds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://supabase.com?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm%5C_term=devtocta" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;🚀 Learn more about Supabase&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>vectordatabase</category>
      <category>database</category>
      <category>ai</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Supabase: what's new in September 2021</title>
      <dc:creator>Copple</dc:creator>
      <pubDate>Tue, 05 Oct 2021 09:22:15 +0000</pubDate>
      <link>https://dev.to/supabase/supabase-what-s-new-in-september-2021-3id2</link>
      <guid>https://dev.to/supabase/supabase-what-s-new-in-september-2021-3id2</guid>
      <description>&lt;p&gt;Did you know it's been 2 years since the &lt;a href="https://github.com/supabase/realtime/commit/175f649784147af80acfc9ff5be9d160285c76ea" rel="noopener noreferrer"&gt;first commit&lt;/a&gt; to Realtime, our real-time engine for Postgres? Before we even existed as a company! &lt;br&gt;
We spent this month improving docs and content content, improving UX, and &lt;a href="https://twitter.com/thorwebdev/status/1441041268411277322" rel="noopener noreferrer"&gt;onboarding Developer Advocates&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901469-77c45924-56f0-49ad-ab92-914d17e2a7f7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901469-77c45924-56f0-49ad-ab92-914d17e2a7f7.jpg" alt="release-sept-2021"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hackathon v2
&lt;/h2&gt;

&lt;p&gt;To kick off &lt;a href="https://hacktoberfest.digitalocean.com/" rel="noopener noreferrer"&gt;Hacktoberfest&lt;/a&gt;, another Supabase Hackathon is happening &lt;a href="https://supabase.io/blog/2021/09/28/supabase-hacktoberfest-hackathon-2021" rel="noopener noreferrer"&gt;right now&lt;/a&gt;. You've got another 7 days to be in to win a limited edition t-shirt. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901455-51e87e99-13b6-42dc-ac18-5a09c95f8c52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901455-51e87e99-13b6-42dc-ac18-5a09c95f8c52.png" alt="hacktober"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Abort Requests
&lt;/h2&gt;

&lt;p&gt;We added support for &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController" rel="noopener noreferrer"&gt;AbortController&lt;/a&gt; in our Javascript library so that you can abort long-running queries. [&lt;a href="https://supabase.io/docs/reference/javascript/select#aborting-requests-in-flight" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901474-83e4d0d2-0846-4445-8c51-2c9af3ca5413.png" class="article-body-image-wrapper"&gt;&lt;img alt="Supabase_abort_requests" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901474-83e4d0d2-0846-4445-8c51-2c9af3ca5413.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved table management
&lt;/h2&gt;

&lt;p&gt;We've made a number of changes to the Dashboard to expose some great features of PostgreSQL including:&lt;/p&gt;

&lt;h3&gt;
  
  
  Column types
&lt;/h3&gt;

&lt;p&gt;We've improved the column Type field so that it supports your &lt;a href="https://www.postgresql.org/docs/current/sql-createtype.html" rel="noopener noreferrer"&gt;custom types&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901485-986106b5-5182-45a3-bc62-e7faa64f6b7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901485-986106b5-5182-45a3-bc62-e7faa64f6b7e.png" alt="types"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Unique
&lt;/h3&gt;

&lt;p&gt;We've made it simple to add a unique constraint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901461-245fd635-5aca-4589-ac03-a2b0807899f5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901461-245fd635-5aca-4589-ac03-a2b0807899f5.png" alt="is-unique"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit columns
&lt;/h3&gt;

&lt;p&gt;By popular request, you can now view all columns in a table at a glance and edit them in bulk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901451-87b7d91a-639c-427d-9fec-777951bcc7d3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901451-87b7d91a-639c-427d-9fec-777951bcc7d3.png" alt="edit-columns"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cross-schema relationships
&lt;/h2&gt;

&lt;p&gt;We updated our &lt;a href="https://github.com/supabase/grid" rel="noopener noreferrer"&gt;grid&lt;/a&gt; to support relationships across multiple schemas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901463-1ba0d27d-d431-41d5-bd9a-42304480e840.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901463-1ba0d27d-d431-41d5-bd9a-42304480e840.png" alt="relationships"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved Auth Docs
&lt;/h2&gt;

&lt;p&gt;We've revamped the Auth docs - The docs are now broken down into &lt;a href="https://supabase.io/docs/guides/auth/auth-apple" rel="noopener noreferrer"&gt;Authentication&lt;/a&gt; and &lt;a href="https://supabase.io/docs/guides/auth/row-level-security" rel="noopener noreferrer"&gt;Authorization&lt;/a&gt;, and organized alongside our &lt;a href="https://supabase.io/docs/learn/auth-deep-dive/auth-deep-dive-jwts" rel="noopener noreferrer"&gt;Deep Dive&lt;/a&gt; series.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901440-e335a99f-7ee5-4dda-8cee-0b689c5cb311.png" class="article-body-image-wrapper"&gt;&lt;img alt="auth-docs" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901440-e335a99f-7ee5-4dda-8cee-0b689c5cb311.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Low Code demo
&lt;/h2&gt;

&lt;p&gt;Low Code demo, Using Supabase with &lt;a href="http://clutch.io/" rel="noopener noreferrer"&gt;Clutch.io&lt;/a&gt; - &lt;a href="https://twitter.com/_dijonmusters" rel="noopener noreferrer"&gt;@_dijonmusters&lt;/a&gt; ran a &lt;a href="https://www.youtube.com/watch?t=642&amp;amp;v=5fsKMTeBKKY" rel="noopener noreferrer"&gt;session at General Assembly&lt;/a&gt; showing how to use these two tools together to create apps using a low code approach. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/5fsKMTeBKKY" rel="noopener noreferrer"&gt;https://youtu.be/5fsKMTeBKKY&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Community
&lt;/h2&gt;

&lt;p&gt;There was a lot of new content this month.&lt;/p&gt;

&lt;h3&gt;
  
  
  Videos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How I built the #10 product in 30 days - &lt;a href="https://www.youtube.com/watch?v=CS1myTKJBR4" rel="noopener noreferrer"&gt;Gary Tokman [video]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Github OAuth flow with Supabase + React - &lt;a href="https://www.youtube.com/watch?v=jSqTzZk9UMg" rel="noopener noreferrer"&gt;Nader Dabit [video]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Best Stack for Web Developers - &lt;a href="https://www.youtube.com/watch?v=-2s_87QkPEI" rel="noopener noreferrer"&gt;Christopher Kapic [video]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Flutter + Supabase Course - &lt;a href="https://www.youtube.com/watch?v=PjVG6QtUYw4" rel="noopener noreferrer"&gt;Abhishvek [video]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;React Native Mobile Auth - &lt;a href="https://www.youtube.com/watch?v=aBuB-Q6vHDE" rel="noopener noreferrer"&gt;Aaron Saunders [video]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Self Hosting Supabase - &lt;a href="https://www.youtube.com/watch?v=HCqta43JHkU" rel="noopener noreferrer"&gt;Kelvin Pompey [video]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Teta Flutter Frontend builder - &lt;a href="https://www.youtube.com/watch?v=rooTglpUuvE" rel="noopener noreferrer"&gt;Teta Team [product]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Magic Link + Route Controls in Next.js - &lt;a href="https://www.youtube.com/watch?v=oXWImFqsQF4" rel="noopener noreferrer"&gt;Nader Dabit [Video]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Supabase in 6 minutes - &lt;a href="https://www.youtube.com/watch?v=ogEitL8RwtQ" rel="noopener noreferrer"&gt;Nader Dabit [video]&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Twitter
&lt;/h3&gt;

&lt;p&gt;We hit 16.5k followers. &lt;a href="https://twitter.com/supabase/status/1441428275176247302" rel="noopener noreferrer"&gt;Follow us&lt;/a&gt; there for advance frontend tips and 👁️⚡👁️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901479-91226fcc-4c25-4c8f-be62-761d5d500b1d.png" class="article-body-image-wrapper"&gt;&lt;img alt="twitter" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901479-91226fcc-4c25-4c8f-be62-761d5d500b1d.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub
&lt;/h3&gt;

&lt;p&gt;Not far from 20K stars: &lt;a href="http://github.com/supabase/supabase" rel="noopener noreferrer"&gt;github.com/supabase/supabase&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901472-6f4e2bd0-ba6a-4572-b77a-44dfc3c69675.png" class="article-body-image-wrapper"&gt;&lt;img alt="stars" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901472-6f4e2bd0-ba6a-4572-b77a-44dfc3c69675.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://repository.surf/supabase" rel="noopener noreferrer"&gt;repository.surf/supabase&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Discord
&lt;/h3&gt;

&lt;p&gt;Our Discord is growing fast. Come hangout with 3500+ developers building on Supabase today: &lt;a href="http://discord.supabase.com" rel="noopener noreferrer"&gt;discord.supabase.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901449-4cead844-d1c2-4226-941d-2525c2f745ef.png" class="article-body-image-wrapper"&gt;&lt;img alt="discord" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901449-4cead844-d1c2-4226-941d-2525c2f745ef.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hiring
&lt;/h2&gt;

&lt;p&gt;We're Hiring &lt;a href="https://about.supabase.com/careers/sre" rel="noopener noreferrer"&gt;SREs&lt;/a&gt;. We're fully remote and we love Open Source. &lt;a href="https://about.supabase.com/careers" rel="noopener noreferrer"&gt;See open roles&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901458-d6f601a5-45de-41a0-bcec-35dba385cd47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F10214025%2F135901458-d6f601a5-45de-41a0-bcec-35dba385cd47.png" alt="hiring"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming Next
&lt;/h2&gt;

&lt;p&gt;We're warming up for another Launch Week! Last time was "&lt;a href="https://supabase.io/blog/2021/07/22/supabase-launch-week-sql" rel="noopener noreferrer"&gt;Launch Week II: the SQL&lt;/a&gt;". We're going to need another month to come up with a good pun again, so we'll aim for November.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get started
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Start using Supabase today: &lt;strong&gt;&lt;a href="https://app.supabase.io/" rel="noopener noreferrer"&gt;app.supabase.io&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Make sure to &lt;strong&gt;&lt;a href="https://github.com/supabase/supabase" rel="noopener noreferrer"&gt;star us on GitHub&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Follow us &lt;strong&gt;&lt;a href="https://twitter.com/supabase" rel="noopener noreferrer"&gt;on Twitter&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Subscribe to our &lt;strong&gt;&lt;a href="https://www.youtube.com/channel/UCNTVzV1InxHV-YR0fSajqPQ" rel="noopener noreferrer"&gt;YouTube channel&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Become a &lt;strong&gt;&lt;a href="https://github.com/sponsors/supabase" rel="noopener noreferrer"&gt;sponsor&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hacktoberfest</category>
      <category>firebase</category>
      <category>javascript</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Daily email of Wikipedia's Current Events</title>
      <dc:creator>Copple</dc:creator>
      <pubDate>Sun, 26 Apr 2020 12:04:37 +0000</pubDate>
      <link>https://dev.to/kiwicopple/daily-email-of-wikipedia-s-current-events-fid</link>
      <guid>https://dev.to/kiwicopple/daily-email-of-wikipedia-s-current-events-fid</guid>
      <description>&lt;p&gt;&lt;code&gt;tldr&lt;/code&gt;: I built &lt;a href="https://currentevents.email/"&gt;https://currentevents.email&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;For many years I haven't been reading any news at all. &lt;sup&gt;*HackerNews doesn't count&lt;/sup&gt; &lt;/p&gt;

&lt;p&gt;While this is great for my cortisol levels, I do feel a bit uninformed. &lt;/p&gt;

&lt;p&gt;I recently discovered that wikipedia has &lt;a href="https://en.wikipedia.org/wiki/Portal:Current_events"&gt;daily summary of key events&lt;/a&gt; happening around the world.&lt;/p&gt;

&lt;p&gt;I decided that is the perfect replacement for news. I've been reading this every day to keep updated. Although it's not hard, I do find the processes of opening the page everyday a bit tedious.&lt;/p&gt;

&lt;p&gt;Wikipedia supports RSS, but I've never been much of an RSS user. And so while thinking of something to build this weekend I figured I would create a daily, automated email of the events listed on Wikipedia.&lt;/p&gt;

&lt;p&gt;Here is the result: &lt;a href="https://currentevents.email/"&gt;https://currentevents.email&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I built it
&lt;/h2&gt;

&lt;p&gt;The build didn't actually take too long. These are the things I used.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Get the content
&lt;/h3&gt;

&lt;p&gt;First I fetch the html content using &lt;a href="https://github.com/cheeriojs/cheerio"&gt;cheerio&lt;/a&gt;. The content requires a bit of cleaning - removing some of the styling etc - but it was a fairly simple process. Here are the key parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request&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;cheerio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cheerio&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;moment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;moment&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;currentMonth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MMMM_YYYY&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;URL_TO_PARSE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://en.wikipedia.org/wiki/Portal:Current_events/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentMonth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URL_TO_PARSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cheerio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&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;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;removeAttr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;cleanseLinks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Not included here&lt;/span&gt;
  &lt;span class="nx"&gt;styleHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Not included here&lt;/span&gt;
  &lt;span class="nx"&gt;styleLists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Not included here&lt;/span&gt;
  &lt;span class="nx"&gt;styleLinks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Not included here&lt;/span&gt;

  &lt;span class="c1"&gt;// Loop through all days this month&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;startOfMonth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;month&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YYYY-MM-DD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;day&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startOfMonth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;today&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;days&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentDayEvents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;.description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`div#&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YYYY_MMMM_d&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentDayEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&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;h3&gt;
  
  
  2. Create the email template
&lt;/h3&gt;

&lt;p&gt;Anybody who has tried to create a nice email quickly finds that it's nearly impossible to design something which works on all email clients.&lt;/p&gt;

&lt;p&gt;Luckily i found this &lt;a href="https://github.com/leemunroe/responsive-html-email-template"&gt;email template&lt;/a&gt; on Github which did all the hard work.&lt;/p&gt;

&lt;p&gt;I simply removed the content in the email template and replaced it with the &lt;code&gt;currentDayEvents.html()&lt;/code&gt; in the code snippet above.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Sending it to subscribers
&lt;/h3&gt;

&lt;p&gt;I needed a transactional email provider for people to subscribe and to send the emails. I chose &lt;a href="https://sendgrid.com/"&gt;SendGrid&lt;/a&gt;. They provide a hosted signup page and also an API for sending the email.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Sending it every day
&lt;/h3&gt;

&lt;p&gt;The solution to this one was quite cool. I discovered that &lt;a href="https://github.com/features/actions"&gt;Github Actions&lt;/a&gt; can be run on a schedule, so I created a action that runs at 1 minute past midnight every day. Here is the action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Current&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Events&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Bot'&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*'&lt;/span&gt; &lt;span class="c1"&gt;# Run at 1 min past midnight every day&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;bot&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-16.04&lt;/span&gt; &lt;span class="c1"&gt;# Download the server&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt; &lt;span class="c1"&gt;# Check out the code&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt; &lt;span class="c1"&gt;# Set up node&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;12.x'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt; &lt;span class="c1"&gt;# Install the modules&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt; &lt;span class="c1"&gt;# Run the "build" script that I created&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Commit files&lt;/span&gt; &lt;span class="c1"&gt;# Commit all the changes&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git config --local user.email "action@github.com"&lt;/span&gt;
          &lt;span class="s"&gt;git config --local user.name "GitHub Action"&lt;/span&gt;
          &lt;span class="s"&gt;git commit -m "Today's events" --allow-empty&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Push changes&lt;/span&gt; &lt;span class="c1"&gt;# Push the changes to the repo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ad-m/github-push-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;github_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.CURRENT_EVENTS_TOKEN }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SENDGRID_API_KEY=${{ secrets.SENDGRID_API_KEY }} npm run send&lt;/span&gt; &lt;span class="c1"&gt;# Run the email script that I created&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;It took a few hours to build, even though it was quite simple. I also bought the domain name and hosted the content on Netlify, so the set up took a bit of time.&lt;/p&gt;

&lt;p&gt;Feel free to comment if you want to get the full code.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Loading JSON into Postgres</title>
      <dc:creator>Copple</dc:creator>
      <pubDate>Thu, 16 Apr 2020 14:00:03 +0000</pubDate>
      <link>https://dev.to/kiwicopple/loading-json-into-postgres-2l28</link>
      <guid>https://dev.to/kiwicopple/loading-json-into-postgres-2l28</guid>
      <description>&lt;p&gt;Today I had to load some JSON data into Postgres. &lt;/p&gt;

&lt;p&gt;Postgres' &lt;code&gt;COPY&lt;/code&gt; command it expects one JSON object per line rather than a full array.&lt;/p&gt;

&lt;p&gt;For example, instead of a JSON array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Conway"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Richard Feynman"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It needs to be this format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Conway"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Richard Feynman"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It took me a surprisingly long time to get the data into Postgres, but the solution was fairly simple. &lt;/p&gt;

&lt;p&gt;Here's how I did it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convert the data
&lt;/h2&gt;

&lt;p&gt;This is done with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;input.json | jq &lt;span class="nt"&gt;-cr&lt;/span&gt; &lt;span class="s1"&gt;'.[]'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/\\[tn]//g'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; output.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;cat input.json&lt;/code&gt; - read the contents of the file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;| jq -cr '.[]'&lt;/code&gt; - pipe JSON into &lt;a href="https://stedolan.github.io/jq/"&gt;jq&lt;/a&gt; and split it onto every line&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;| sed 's/\\[tn]//g'&lt;/code&gt; - [optional] remove tabs, newlines etc&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;gt; output.json&lt;/code&gt; - output to a new file&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Importing the data
&lt;/h2&gt;

&lt;p&gt;From here it's easiest to ingest the data into a JSONB column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## Create a table&lt;/span&gt;
psql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-p&lt;/span&gt; 5432 postgres &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"CREATE TABLE temp (data jsonb);"&lt;/span&gt;

&lt;span class="c"&gt;## Copy your data in&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;output.json | psql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-p&lt;/span&gt; 5432 postgres &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"COPY temp (data) FROM STDIN;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  That's it
&lt;/h2&gt;

&lt;p&gt;20 seconds of reading, and 1 hour of my time. To get the data out of the table now you can use any of Postgres' amazing JSON support. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="k"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- John Conway&lt;/span&gt;
&lt;span class="c1"&gt;-- Richard Feynman&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Enjoy.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Quick tip: Clone a single folder from Github</title>
      <dc:creator>Copple</dc:creator>
      <pubDate>Fri, 03 Apr 2020 09:31:04 +0000</pubDate>
      <link>https://dev.to/kiwicopple/quick-tip-clone-a-single-folder-from-github-44h6</link>
      <guid>https://dev.to/kiwicopple/quick-tip-clone-a-single-folder-from-github-44h6</guid>
      <description>&lt;p&gt;Sometimes you find a repository on Github and you only really need a single folder. &lt;/p&gt;

&lt;p&gt;How do you get it without cloning the entire repo? &lt;/p&gt;

&lt;p&gt;Luckily Github &lt;a href="https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/"&gt;just implemented&lt;/a&gt; &lt;code&gt;sparse-checkout&lt;/code&gt;. This is a super-quick example of how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example repo
&lt;/h2&gt;

&lt;p&gt;Let's say I wanted to clone Supabase's &lt;a href="https://github.com/supabase/supabase/blob/master/examples/slack-clone-basic/README.md"&gt;example Slack clone&lt;/a&gt;, which lives in the following folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;├── connectors
├── examples
│   ├── slack-clone-basic &lt;span class="c"&gt;# &amp;lt;-- github.com/supabase/supabase/examples/slack-clone-basic&lt;/span&gt;
├── libraries
├── web
└── README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Sparse Checkout
&lt;/h2&gt;

&lt;p&gt;Here are all the steps I would need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Copy an empty repo&lt;/span&gt;
git clone &lt;span class="nt"&gt;--no-checkout&lt;/span&gt; https://github.com/supabase/supabase

&lt;span class="c"&gt;# 2. Move into the empty repo&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;supabase

&lt;span class="c"&gt;# 3. Initialize sparse-checkout&lt;/span&gt;
git sparse-checkout init &lt;span class="nt"&gt;--cone&lt;/span&gt;

&lt;span class="c"&gt;#4. Checkout the folder&lt;/span&gt;
git sparse-checkout &lt;span class="nb"&gt;set &lt;/span&gt;examples/slack-clone-basic
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And viola! Now you have just the folder you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sparse-checkout&lt;/code&gt; was introduced in Git version 2.25. If you get see an error "git: 'sparse-checkout' is not a git command" then you probably need to update. You can use &lt;code&gt;git --version&lt;/code&gt; to see what version you're on.&lt;/p&gt;

&lt;p&gt;If you're on Mac (and used homebrew to install git) you can run &lt;code&gt;brew upgrade git&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Design Tips for Developers</title>
      <dc:creator>Copple</dc:creator>
      <pubDate>Sat, 14 Mar 2020 02:37:05 +0000</pubDate>
      <link>https://dev.to/supabase/design-tips-for-developers-1akg</link>
      <guid>https://dev.to/supabase/design-tips-for-developers-1akg</guid>
      <description>&lt;p&gt;Developers aren't well-known for their design skills. I suspect that poor design/UX in open source projects is the primary reason they aren't more successful. Usually the projects are technically brilliant - fast, well tested, and well maintained. But without a loveable interface users won't get hooked.&lt;/p&gt;

&lt;p&gt;Perhaps you're the type of developer who is put off by any blog post with "Design" in the title. If you are, then I will say this up-front: design is about doing less rather than doing more. I don't advocate over-design, and I recommend erring on the side of simplicity. This blog post will only elaborate this point.&lt;/p&gt;

&lt;p&gt;As with anything, being "20% good" at design will get you 80% of the way there. This article outlines some of the tools and tips I have picked up over the years that will make you a "20%" designer. I'm not going to go into UX (even though it's more important) because I think learning how to think in simple design patterns is the baseline for creating usable products. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: this article was modified from my original blog post: &lt;a href="https://paul.copplest.one/blog/design.html"&gt;https://paul.copplest.one/blog/design.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building a design-y sense&lt;/li&gt;
&lt;li&gt;Creating a logo

&lt;ul&gt;
&lt;li&gt;Designing an Icon&lt;/li&gt;
&lt;li&gt;Designing the logo text/name&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Colors&lt;/li&gt;
&lt;li&gt;Fonts&lt;/li&gt;
&lt;li&gt;Icons&lt;/li&gt;
&lt;li&gt;Images and Illustrations

&lt;ul&gt;
&lt;li&gt;Illustrations&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Branding&lt;/li&gt;
&lt;li&gt;Using a CSS framework&lt;/li&gt;
&lt;li&gt;Design tools&lt;/li&gt;
&lt;li&gt;More reading, tips, and tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building a design-y sense
&lt;/h2&gt;

&lt;p&gt;This step isn't necessary but it's the thing that gave me the most improvement for the least effort. It will improve your "design sense", and give you an idea of your personal design style. The steps are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visit &lt;a href="https://dribbble.com"&gt;Dribbble&lt;/a&gt; (I have no affiliation) and sign up for their weekly newsletter &lt;/li&gt;
&lt;li&gt;When you receive the weekly newsletter, click the "Most Popular Shots" link&lt;/li&gt;
&lt;li&gt;Browse through the first page of the most popular shots for that week&lt;/li&gt;
&lt;li&gt;"Favourite" any that you like&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This takes about 5 minutes each week. After a few weeks you can go back and look at your favourites. You'll likely find a theme in your favourites - perhaps the same color, or you like angles, etc. &lt;/p&gt;

&lt;p&gt;You'll also notice the up-and-coming trends. In the past it was soft shadows and sharp angles. The current trend is illustrations of people. Start feeding these trends into your projects. Even if you aren't a big fan of them, it's good to remember that design is effective when it appeals to your target audience and not yourself. &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a logo
&lt;/h2&gt;

&lt;p&gt;Logos are a great place to start since the logo design carries over to your software/site. Logos vary for different mediums (print, digital, etc), but since you're reading I'll assume you're a developer, and so your logo will be used on a website, on an app, or in software. &lt;/p&gt;

&lt;p&gt;If this describes your use-case it means your logo should consist of two parts, and should follow a few basic patterns. You should start with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An icon&lt;/li&gt;
&lt;li&gt;Logo text/name&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Designing an Icon
&lt;/h3&gt;

&lt;p&gt;Here are some useful guidelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Square&lt;/strong&gt;: Make sure it fits evenly into a square. This is important because it will be in a &lt;code&gt;favicon&lt;/code&gt; or possibly an app icon. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Symetrical&lt;/strong&gt;: By symetrical, I mean that it should take up an even amount of space within the square. Logos can look a bit awkward when they are squashed to one side or if there is lots of space in one area of the square.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple&lt;/strong&gt;: This is by far the most important rule. There is no such thing as an icon which is too simple. Make sure it is legible when scaled down to 32x32 px. This is how it will look in the tab of a browser. Also keep the colors simple - you can use color, but it's best if you stick with just one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Designing the logo text/name
&lt;/h3&gt;

&lt;p&gt;You have a bit more freedom with this one. I would recommend, however, that you make this just a simple color - for example, black or dark grey. Let the icon carry the logo, and let font that you choose for the text set the brand. Whichever font you choose for the text, you should (probably) use it in all the headings of your site/app/software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Colors
&lt;/h2&gt;

&lt;p&gt;The best advice I can give for colors is to choose one which is vibrant and that's all. Every other color should be white or black.&lt;/p&gt;

&lt;p&gt;Ok, now that I have got that out of the way, you &lt;em&gt;can&lt;/em&gt; use other colors (for things like alerts, warnings, etc), and a few different grey tones.&lt;/p&gt;

&lt;p&gt;If I'm building a tech product, I usually begin my designs with what I call "startup blue". You've probably seen this color on a million different tech sites. The hex code for startup blue is somewhere close to&lt;span&gt;#2B70F6&lt;/span&gt;. There are lots of reasons for this, but none more important than it's safe. After you have created your site, feel free to play with this color.&lt;/p&gt;

&lt;p&gt;For everything you need to know about colors, I highly recommend reading &lt;a href="https://refactoringui.com/previews/building-your-color-palette/"&gt;Building your color pallete&lt;/a&gt; by Refactoring UI. After you have a good grasp on the concepts, you can use &lt;a href="https://www.colorbox.io/"&gt;colorbox.io&lt;/a&gt; to build your custom pallete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fonts
&lt;/h2&gt;

&lt;p&gt;There are three guidelines I could give here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aim for only one or two different fonts, three if you &lt;em&gt;absolutely&lt;/em&gt; need it. &lt;/li&gt;
&lt;li&gt;Sans-serif is safest for headings and the font should (probably) be bold, symmetrical&lt;/li&gt;
&lt;li&gt;Content can be serif but it's fine to be san-serif. Serif fonts are ostensibly easier to read for long paragraphs because the little "tails" on the letters make it easier on the eyes, but this is more true in printed media than on pixilated screens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I mentioned in the logo section, you (probably) want your heading font to match your logo font, but it's not critical.&lt;/p&gt;

&lt;p&gt;Fonts are something that you have to play with a lot to find something you like. &lt;a href="https://fonts.google.com/"&gt;Google Fonts&lt;/a&gt; is useful here (if you don't have an aversion to Google) since you don't have to go through the hassle of downloading/uploading the font to try it out. I'm personally trying to move away from Google so I'm slowly &lt;a href="https://quickfont.xyz/"&gt;building up a site&lt;/a&gt; to achieve the same thing, except the fonts are served from GitHub.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Icons
&lt;/h2&gt;

&lt;p&gt;Try to use only a few icons. Icons actually add very little, practically speaking, unless you are able to replace some words completely with the icon. A great example is the ≡ 'hamburger icon' which completely replaces the need to have "Show menu" in navbars. Quite honestly, I think even "good" designers use too many icons. &lt;/p&gt;

&lt;p&gt;That said, a few icons can make a site look more finished. Just make sure the icons have a consistent "theme": they should have the same stroke thickness; if some are rounded, they should all be rounded; keep the colors consistent. &lt;/p&gt;

&lt;p&gt;And once again, simplify! The point of an icon is to reduce the cognitive load on a user. Try to stick with icons that have very little detail.&lt;/p&gt;

&lt;p&gt;Here are the best (free) resources that I commonly use&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.flaticon.com/"&gt;flaticon.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenounproject.com/"&gt;thenounproject.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fontawesome.com"&gt;fontawesome.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://icons8.com/line-awesome"&gt;icons8.com/line-awesome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ikonate.com"&gt;ikonate.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://icomoon.io/"&gt;icomoon.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/coreui/coreui-icons/tree/1.0.0/"&gt;core-ui&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Images and Illustrations
&lt;/h2&gt;

&lt;p&gt;Images and illustrations largely serve the purpose of filling space and emphasizing your message. Which one you choose is a matter of preference, but try not to mix the two.&lt;/p&gt;

&lt;h3&gt;
  
  
  Illustrations
&lt;/h3&gt;

&lt;p&gt;Illustrations can really bring a website/app to life. They are less important in software (in fact they would probably look stupid in most software) but work well on landing pages. However illustrations are the hardest to nail, because they are hard quite bespoke which makes it difficult to have a consistent look across all of them. &lt;/p&gt;

&lt;p&gt;Try to create your site first without illustrations (I doubt this will be a problem for most readers), then as a final step add a few illustrations if you have gaps to fill. There are some really great resources starting to pop up which have some free, lightweight illustrations to try. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.humaaans.com/"&gt;humaaans.com&lt;/a&gt; --&amp;gt; you've probably started seeing these everywhere&lt;/li&gt;
&lt;li&gt;&lt;a href="https://undraw.co/"&gt;undraw.co&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://icons8.com/ouch/"&gt;icons8.com/ouch&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.avataaars.com/"&gt;avataaars.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freepik.com/"&gt;freepik.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Images
&lt;/h3&gt;

&lt;p&gt;Images are much easier than illustrations because the quantity of stock photos is so much larger than stock illustrations, and if you want to move the designs in-house in the future then it's far easier to find a competent photographer than a competent illustrator.&lt;/p&gt;

&lt;p&gt;Once again, images are far more effective on websites than software (which probably goes without saying, but I'm staying it anyway).&lt;/p&gt;

&lt;p&gt;It can be difficult to make images feel "part" of the site - quite often they just seem like they are floating in place. It just takes some small things to mitigate this. For example, you can make your images stretch full-width. Or if your site uses lots of rounded corners, add rounded corners to your floating images. If your site uses drop-shadows, add them to your images. &lt;/p&gt;

&lt;p&gt;Adding text onto images is a little bit risky since it can make the text hard to read. If you are going to do this, add a very subtle drop shadow to the text. &lt;br&gt;
Alternatively you can consider adding an overlay between the text and the image. &lt;/p&gt;

&lt;p&gt;The best sites I use for images are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://unsplash.com/"&gt;unsplash.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pixabay.com/"&gt;pixabay.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pexels.com/"&gt;pexels.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Branding
&lt;/h2&gt;

&lt;p&gt;Consistency is the only thing you need to remember here. For a product to feel cohesive, it must be consistent. Some guidelines are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose one color and use it everywhere. For everything else use black or dark grey.&lt;/li&gt;
&lt;li&gt;Choose one font and use it everywhere&lt;/li&gt;
&lt;li&gt;Text sizes should always be the same (with the exception of headers). Don't make one paragraph 12px and another 14px&lt;/li&gt;
&lt;li&gt;Use consistent padding&lt;/li&gt;
&lt;li&gt;Make things line up. When we see things for the first time, it's easier to make sense of fewer "blocks" of things. We can achieve this by grouping things together and aligning them. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't fall into the trap of "redesigning sections". When you start designing it feels like every part of your site should look slightly different. In fact the opposite is true. Try to use the same layouts everywhere. When a person sees a something for the first time their brain has to make sense of everything they are seeing. There is a cognitive load while they determine what is the important information, and this is mentally an uncomfortable process. If you can reuse the same layouts throughout your site then your users' cognitive load is lessened, and they only have to feel uncomfortable once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using a CSS framework
&lt;/h2&gt;

&lt;p&gt;If you're building a website, I highly recommend keeping your CSS framework and JS framework separate. Wherever possible avoid using "locked in" frameworks like ReactStrap, and instead opt for "class based" CSS frameworks. Once you become comfortable with this then your designs can be implemented anywhere - whether you use HTML, React, Vue, or whatever latest and greatest framework you decide to use.&lt;/p&gt;

&lt;p&gt;I would also recommend sticking with a "utility-first" CSS framework. Take your pick of either &lt;a href="https://bulma.io"&gt;Bulma&lt;/a&gt; or &lt;a href="https://tailwindcss.com/"&gt;Tailwind&lt;/a&gt; and invest a day into learning how they work. This day will pay off in spades - prototyping with either of these is quicker than designing then implementing from scratch. Avoid ever using the &lt;code&gt;style&lt;/code&gt; tag. Just use classes for everything from layout to look and feel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design tools
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.figma.com"&gt;Figma&lt;/a&gt;. That's all you really need. Forget about Sketch and Invision. Figma has vector design capabilities, clickable prototypes, commenting, and it's collaborative. And it's free(mium)! Invest a little bit of time into using it - video tutorials are quite helpful here - and then live inside it for anything that you need to do for design and editing. &lt;/p&gt;

&lt;p&gt;I'm really a fan-boy of Figma, but for good reason. I've tried a lot of other tools in the past and none are as good (and holistic). If you're working with photos then you may also need Photoshop but as a developer the types of things that you need to do with photos are usually just compressing and resizing, which can be better achieved with an asset pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  More reading, tips, and tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://news.ycombinator.com/item?id=22126731"&gt;The HN discussion of this very post&lt;/a&gt;. A lot of great advice in the comments.
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.julian.com/guide/growth/landing-pages"&gt;Julian Landing page&lt;/a&gt;: This is the best guide I know for building a landing page. One additional tip: if you are using a Hero on your landing page, make it only &lt;code&gt;70vh&lt;/code&gt; and have a "More" button below it. Too many websites have a &lt;code&gt;100vh&lt;/code&gt; hero, and it isn't immediately apparent to the user that they can scroll down.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/LisaDziuba/Awesome-Design-Tools"&gt;Design Tools for Everything&lt;/a&gt;: A huge list of tools. I personally find these lists a bit daunting but it does have something for everybody if you can be bothered combing through it.&lt;/li&gt;
&lt;li&gt;You may occasionally want to implement some CSS layouts outside of the grid systems provided by Bulma or Tailwind. A couple of resources for learning are &lt;a href="https://testdriven.io/blog/css-grid"&gt;testdriven.io/blog/css-grid&lt;/a&gt; and &lt;a href="https://every-layout.dev"&gt;every-layout.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;An awesome resource for creating printable UI mockups/wireframes templates: &lt;a href="https://github.com/alexadam/printable-mockups"&gt;github.com/alexadam/printable-mockups&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rules for Intuitive UX - &lt;a href="https://learnui.design/blog/4-rules-intuitive-ux.html"&gt;learnui.design&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>design</category>
      <category>css</category>
      <category>supabase</category>
    </item>
    <item>
      <title>How to Agile</title>
      <dc:creator>Copple</dc:creator>
      <pubDate>Wed, 11 Mar 2020 01:18:20 +0000</pubDate>
      <link>https://dev.to/supabase/how-to-agile-353c</link>
      <guid>https://dev.to/supabase/how-to-agile-353c</guid>
      <description>&lt;p&gt;Ask 3 developers "what is agile" and you'll get four different answers. That's because there is no "definitive agile", and the &lt;a href="https://agilemanifesto.org"&gt;Agile Manifesto&lt;/a&gt; which started it all is extremely loose (on purpose!). &lt;/p&gt;

&lt;p&gt;This article will give you a brief background on agile, but more importantly it'll give you a few tips on how to apply it to your own team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to do Agile&lt;/li&gt;
&lt;li&gt;A brief history of Technical Project Delivery&lt;/li&gt;
&lt;li&gt;The Agile Manifesto&lt;/li&gt;
&lt;li&gt;Common Methodologies&lt;/li&gt;
&lt;li&gt;Agile Toolset&lt;/li&gt;
&lt;li&gt;Interesting Implementations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Don't start with processes
&lt;/h2&gt;

&lt;p&gt;I won't bury the lede. If you're looking to build an agile team, the best approach is to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with as little process as needed. I can't emphasis this step enough, start with &lt;strong&gt;the minimum possible process&lt;/strong&gt;. This is the part that most teams get wrong.&lt;/li&gt;
&lt;li&gt;Get regular feedback from your team on pain points and get their buy-in on ways to improve the process.&lt;/li&gt;
&lt;li&gt;Start adding or removing processes whenever required. You can pull from a wide toolset of useful practices to make your team more effective. There is no need to be dogmatic about any particular methodology.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What &lt;em&gt;might&lt;/em&gt; this look like when you are getting started?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every day&lt;/strong&gt;: Do a standup where everyone gets together. This will possibly be the only time your developers spend together each day. Don't be too uptight about how the standup is run, it's great for culture when the managers get out of the way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every week&lt;/strong&gt;: Once per week do a retrospective where you ask your team what can be improved about the &lt;em&gt;process&lt;/em&gt;. It's important to highlight the distinction of product vs process. You don't want to talk about product improvements in this meeting. Instead the team should think of activities that make them more effective at delivering. More/less meetings, more/less planning, more/less tracking of productivity, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll probably end up with a process which is completely unique to your team, even within the same company.&lt;/p&gt;

&lt;h2&gt;
  
  
  A brief history of Software Project Management
&lt;/h2&gt;

&lt;p&gt;Before digging deeper into Agile it might be worthwhile knowing how software development got to where it is.&lt;/p&gt;

&lt;p&gt;In the not-so-distant past, a Waterfall development approach was ubiquitous. Quite simply it outlined the phases which a technical project would move through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Gather all requirements 
2. Design the entire system 
3. Develop the entire system 
4. Test everything and patch any bugs 
5. Deploy everything in one go 
6. Maintain (sometimes)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks quite similar to current techniques, except that it was done in one "monolithic" effort. &lt;/p&gt;

&lt;p&gt;No matter how big the project, or how long it was expected to take, the project would be shoved through this pipeline. Once a transition from one stage to another was made there was no going back.&lt;/p&gt;

&lt;p&gt;The problem with Waterfall is that big projects would get delivered and everyone would discover that the requirements have changed. Or the requirements were incorrect to start with. Or the people who started the project were gone and nobody knew why they had those requirements to start with. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Agile Manifesto
&lt;/h2&gt;

&lt;p&gt;Eventually some smart techies decided that there needed to be a more effective way. So they got together in a ski resort and decided to develop the &lt;br&gt;
&lt;a href="https://agilemanifesto.org"&gt;agile manifesto&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's &lt;em&gt;extremely&lt;/em&gt; brief, but I rarely meet developers who've read the manifesto so I'll list the four core values here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Individuals and interactions over processes and tools
2. Working software over comprehensive documentation
3. Customer collaboration over contract negotiation
4. Responding to change over following a plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are also &lt;a href="https://agilemanifesto.org/principles.html"&gt;12 Principles&lt;/a&gt; which I'll let you read on your own.&lt;/p&gt;

&lt;p&gt;If you've been using agile methodologies in your company, you'll probably be shocked to read the core values. People over processes? That doesn't sound much like the agile shops I worked in. Responding to change? Most companies stubbornly force teams to use their "one true agile".&lt;/p&gt;

&lt;p&gt;OK, I'll admit "contract negotiation" isn't a common activity in startups, but if you adapt the third value to "listen to your customers" then you've got a pretty solid set of values for managing a software team. &lt;/p&gt;

&lt;p&gt;Notice as well what &lt;em&gt;isn't&lt;/em&gt; there. It doesn't say you have to do any specific process. In fact it's not far off telling you the opposite: throw away the processes, plans, and structure; expect change and let your people guide the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agile Toolset
&lt;/h2&gt;

&lt;p&gt;If you've religiously followed what I said up until now then you'll quickly find all your problems are not yet solved. It turns out that processes &lt;strong&gt;are&lt;/strong&gt; important, it's just not clear at the start &lt;strong&gt;which&lt;/strong&gt; processess they are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Processes
&lt;/h3&gt;

&lt;p&gt;Here are six broad practices that I use and adapt. Most agile methodologies seem to be some variation of these. Use them only if they solve specific problems in your team. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stand ups&lt;/strong&gt;: A daily meeting where everyone answers 3 questions: what they worked on yesterday; what they're working on today; and if they have any blockers. Great for culture and an opportunity to clear confusion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrospectives&lt;/strong&gt;: A meeting to discuss the process that the team is using and any improvements to consider. Typically there are 3 questions: what went well? what didn't go well? and what should we do differently? Great for improving your team's agile process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backlogs&lt;/strong&gt;: A list of all the tasks that need to be completed. Great for deflecting unimportant tasks from your team's important work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sprints&lt;/strong&gt;: A set timeframe for the team to try complete an agreed amount of work. These are typically short - one or two weeks. A meeting held at the start of sprint to discuss what tasks needs to be done. The tasks are usually pulled from the backlog. Great for team productivity (if done correctly).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pair programming&lt;/strong&gt;: When 2 programmers work together for a task or timeframe. Usually one person will be driving the interaction and the other is more passive. Great for building team knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pull requests&lt;/strong&gt;: A review process for code. When one developer has completed a task or needs feedback, they can create a pull request (using version control) for another developer to review. Great for code quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Roles
&lt;/h3&gt;

&lt;p&gt;As your team grows it's sometimes usuful to introduce roles and delegate responsibilities. These are the roles that I find are the most useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Manager / Scrum master&lt;/strong&gt;: this is a bit of a thankless job. Usually their key responsibility is to track how everything is going. However, developers hate being asked when things will be delivered. I like to reframe the role: this person should concentrate on &lt;em&gt;reducing&lt;/em&gt; admin tasks for developers so they can focus on their work. New admin tasks should only be introduced by the developers (during the retro).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product Owners&lt;/strong&gt;: usually a member of company who isn't a techie. This role is for the business side to help priorities tasks. They don't have to make the final decisions on what to build, but their input can be invaluable. Try to pick someone who has a good social standing in the company and will "have the developers' backs". This person is the bridge between techies and the rest of the company and they can really help shield the tech team from unreasonable demands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Methodologies
&lt;/h3&gt;

&lt;p&gt;There are a lot of Agile Methodologies but two are predominantly used these days: Kanban and Scrum. If you're new to Agile it can be good to use these as a starting point and them slowly adapt them. Just make sure you remember the fourth agile value: "Responding to change over following a plan". I won't got into them in depth here but here is how I see their usefulness:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kanban&lt;/strong&gt;: great for consistent, continuous improvements. Usually you'd lay out the entire set of tasks into one board, and then have the developers pull from the top of the list. Slowly, steadily, the tasks get done without a mad rush for some arbitrary deadline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scrum&lt;/strong&gt;: great for working towards deadlines. The tasks get chunked up into short sprints - periods of work usually one or two weeks long. At the end of the sprint you assess how much work was done and you can forecast or adjust the deadlines as required. Scrum makes it a bit easier to push out new features compared to Kanban, simply because you can stagger the dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interesting implementations
&lt;/h2&gt;

&lt;p&gt;Learning how other teams do agile is useful in a "the journey is the destination" sort of way. You can learn what worked for &lt;em&gt;that&lt;/em&gt; company, at &lt;em&gt;that&lt;/em&gt; time, with &lt;em&gt;those&lt;/em&gt; people. If you ask these companies today what their agile processes look like then it will almost certainly have changes. So take only what you need from these case studies, but don't get too enamoured into thinking they have the perfect process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spotify: "Autonomous Tribes"
&lt;/h3&gt;

&lt;p&gt;Spotify used to employ a &lt;a href="https://labs.spotify.com/2014/03/27/spotify-engineering-culture-part-1/"&gt;fairly verbose framework&lt;/a&gt; where they organised their teams into Tribes, Chapters, and Guilds. They used a very decentralised approach to development, modelling their internal software architecture on the open source model of loose dependencies. If you wanted to identify which agile methodology they use, they would say "it depends which team". &lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon: "Press Releases"
&lt;/h3&gt;

&lt;p&gt;Not so much of a framework but a requirements gathering process. Amazon write "Press Releases" before working on any particular feature. The idea behind this is to be customer driven and to improve clarity. It also answers the question of "why". Much of the work tech teams is driven by blind requirements. Press Releases help to motivate teams by understanding why they are working on a feature and the impact it will have. &lt;/p&gt;

&lt;h3&gt;
  
  
  Early WhatsApp: "No process"
&lt;/h3&gt;

&lt;p&gt;&lt;small&gt;(I can't actually remember where I heard this. I think it was a video of a Whatsapp employee talking at a conference. Please share if you know which video I am talking about.)&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;In a video I saw, a Whatsapp employee said that every developer had their own backlog. They had full autonomy over what they would work on, with one rule: prioritise bugs over anything else. &lt;/p&gt;

&lt;p&gt;He said that he felt so much empowerment and ownership with this approach, that when his friend told him about a bug during a party he pulled out his laptop and fixed the bug immediately.&lt;/p&gt;

&lt;p&gt;Honestly I don't know how this worked when trying to push new features. But I can imagine that if you give your developers autonomy over what they want to work on (maybe pulling from a company backlog) and no set timelines, they will be the most loyal techies in the world. Meaning that they will stay with your company for three years instead of two.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>scrum</category>
      <category>kanban</category>
      <category>supabase</category>
    </item>
  </channel>
</rss>
