<?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: Timothy</title>
    <description>The latest articles on DEV Community by Timothy (@timlrx).</description>
    <link>https://dev.to/timlrx</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%2F575154%2Ff6220e22-1da9-4ff2-a575-bfafb166118d.png</url>
      <title>DEV Community: Timothy</title>
      <link>https://dev.to/timlrx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/timlrx"/>
    <language>en</language>
    <item>
      <title>Building a Responsible AI Solution - Principles into Practice</title>
      <dc:creator>Timothy</dc:creator>
      <pubDate>Mon, 10 Jan 2022 15:54:47 +0000</pubDate>
      <link>https://dev.to/timlrx/building-a-responsible-ai-solution-principles-into-practice-11p4</link>
      <guid>https://dev.to/timlrx/building-a-responsible-ai-solution-principles-into-practice-11p4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This is part 2 of my series of posts on fairness in AI, reflections from a participant in the Monetary Authority of Singapore's (MAS) &lt;a href="https://www.mas.gov.sg/news/media-releases/2021/mas-launches-global-challenge-to-accelerate-innovation-in-responsible-ai-solutions"&gt;Global Veritas Challenge&lt;/a&gt;. In my &lt;a href="https://www.timlrx.com/blog/a-human-centric-approach-to-fairness-in-ai"&gt;first post&lt;/a&gt;, I discussed the need to adopt a human-centric approach when dealing with issues of fairness in AI systems. After hours of brainstorming, user interviews and smashing bits of code together, we created &lt;a href="//www.verifyml.com"&gt;VerifyML, an open-source framework to help organisations build fair and responsible models&lt;/a&gt;. The solution was one of the three &lt;a href="https://www.mas.gov.sg/news/media-releases/2021/winners-of-the-global-veritas-challenge-2021"&gt;winning submissions&lt;/a&gt; of the Veritas challenge!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 minutes VerifyML pitch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My teammates have written about &lt;a href="//www.verifyml.com"&gt;VerifyML&lt;/a&gt; in detail, so if you are interested in giving it a spin, check out the following introductory posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/cylynx/introducing-verifyml-314b8e0a1c6b"&gt;Introducing VerifyML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/cylynx/a-quickstart-guide-to-verifyml-pt-1-c1a751194a68"&gt;A Quickstart Guide to VerifyML Part 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/cylynx/a-quickstart-guide-to-verifyml-pt-2-7867d4ba31b0"&gt;A Quickstart Guide to VerifyML Part 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/cylynx/verifyml-where-it-stands-among-other-ai-fairness-toolkits-8e6cad149b2"&gt;Comparing VerifyML, AI Fairness 360 and Fairlearn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, I take a step back and share some of the things I have learned while developing this solution. I start from the user interviews and feedback that we have gathered, before discussing existing tools in the model governance space, and concluding with how we designed a solution that addresses the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  User interviews and feedback
&lt;/h2&gt;

&lt;p&gt;The competition gave us many opportunities to engage with a variety of stakeholders who were involved in trying to implement responsible AI workflows in their organisations. While the organisations all have slightly different workflows, there were three recurring pain points that caught our attention:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Friction in exchange of information between teams&lt;/li&gt;
&lt;li&gt;Difficulty in synchronizing data science code with docs&lt;/li&gt;
&lt;li&gt;Difficulty aligning code with regulatory requirements&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Friction in exchange of information between teams
&lt;/h3&gt;

&lt;p&gt;Recognising that the problem is not only one faced by data scientists, but a multi-stakeholder problem that involves product owners, data teams, compliance teams and system engineers shaped our thinking and approach to the problem. Responsible AI is a process, not an outcome, and our solution should be the medium that enables the process to be conducted more efficiently and effectively. The solution also must be the common interface that allows different parties to weigh in throughout the process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Difficulty in synchronizing data science code with docs
&lt;/h3&gt;

&lt;p&gt;This has always been a nagging problem in our consultation projects so it does not come as a surprise that many data scientists also face challenges synchronizing their code with their documentation. In most projects, documentation is often seen as the least glamorous part of the job and is done only after the project is completed. It is usually hastily written in Microsoft Word and stored in Sharepoint or some internal knowledge base.&lt;/p&gt;

&lt;p&gt;This leads to two problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The documentation does not capture the process of building the model and subsequent changes.&lt;/li&gt;
&lt;li&gt;Documentation is not easily discoverable, searchable or editable by others in the team.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Difficulty aligning code with regulatory requirements
&lt;/h3&gt;

&lt;p&gt;This might be more relevant to the competition that we are participating in, but in sectors where machine learning and AI models will be regulated, it is often quite a stretch to align the process which the model is developed with the regulatory requirements which often comes in a form of a multiple questionnaire checklist.&lt;/p&gt;

&lt;p&gt;Data scientists do not have the bandwidth or do not think they should be burdened with trying to align their models with regulatory requirements. They also do not know what metrics that they should be using for a given business problem resulting in either a "spray and pray" approach or simply just omitting such fairness analysis.&lt;/p&gt;

&lt;p&gt;Meanwhile, accessors / auditors may not have the technical capabilities to understand all the harms and benefits associated with the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools and solutions in the model governance space
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LetMPbes--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jiiejfbgvj5l2j0q7bhb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LetMPbes--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jiiejfbgvj5l2j0q7bhb.jpg" alt="abstract puzzle" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having teased out the pain points from our users, we wanted to understand more about the lay of the land and what existing tools and solutions are available. The worse possible outcome of the competition would be to spend a month re-inventing the wheel and creating an inferior version of what is out there in the market. We also did not want our solution to be a compliance exercise where the whole thing becomes just a checklist resulting in teams trying to game the system and subvert the process.&lt;/p&gt;

&lt;p&gt;With this in mind, we began our explorations in the model governance space. I use the term here quite liberally to refer to the whole suite of solutions meant to help build and deploy machine learning models into production.&lt;/p&gt;

&lt;p&gt;The model governance space could be categorized into the following three areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model building and experimentation&lt;/li&gt;
&lt;li&gt;Model versioning, deployment and release&lt;/li&gt;
&lt;li&gt;Monitoring and quality control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a brief overview of the three areas. Model building and experimentation tools normally include a large library of algorithms which a data scientist or analyst could easily create machine learning pipelines. It includes popular open-source tools like &lt;a href="https://scikit-learn.org/stable/"&gt;scikit-learn&lt;/a&gt;, as well as commercial solutions like &lt;a href="https://www.datarobot.com/"&gt;Data Robot&lt;/a&gt; and &lt;a href="https://www.h2o.ai/"&gt;h2o&lt;/a&gt; which might have data connectors to existing data marts or databases.&lt;/p&gt;

&lt;p&gt;To push a model into production, there are additional concerns which the tools in the versioning, deployment and release space aim to solve. This includes obtaining adequate infrastructure to run the model reliably and facilitating easy model release or rollback. Solutions in the MLOps space includes &lt;a href="https://www.kubeflow.org/"&gt;Kubeflow&lt;/a&gt;, &lt;a href="https://www.pachyderm.com/"&gt;Pachyderm&lt;/a&gt; and &lt;a href="https://algorithmia.com/"&gt;Algorithmia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While tools in the model experimentation space normally include diagnostic charts on a model's performance, there are also specialised solutions that help ensure that the deployed model continues to perform as they are expected to. This includes the likes of &lt;a href="https://github.com/SeldonIO/seldon-core"&gt;seldon-core&lt;/a&gt;, &lt;a href="https://whylabs.ai/"&gt;why-labs&lt;/a&gt; and &lt;a href="https://www.fiddler.ai/"&gt;fiddler.ai&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This categorisation is relatively simplistic and there certainly are numerous solutions that overlap in capabilities and are positioning themselves as end-to-end machine learning platforms.&lt;/p&gt;

&lt;p&gt;The problem space that we are dealing with involves machine learning issues but also compliance and operation processes. Some of the existing solutions support responsible AI development by providing model explainability and fairness analysis, but these explainability or fairness reports tend to be consumed by technical experts i.e. the data scientist. There seems to be a gap for solutions to cater to less technical stakeholders, including internal management teams as well as customers.&lt;/p&gt;

&lt;p&gt;Existing solutions in the monitoring and quality control space also served as a great source of inspiration in developing a model governance solution. There are some attempts at placing a regulatory layer on top of these systems, but it strikes me as an odd fit simply because these existing solutions do not cater to non-technical users. Nonetheless, the idea of monitoring the results of a machine learning model in production and providing reports on performance drift or degradation in other aspects of a model is something we adapted as part of our solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing VerifyML
&lt;/h2&gt;

&lt;p&gt;Having bashed our way around the model governance ecosystem, we needed to distil our knowledge to a minimum viable product. When designing a solution for a competition, especially against other competitors with existing products, I find it very helpful to identify a niche to position ourselves. Essentially, we want it to be a competition of ideas rather than who has the best technical implementation. It's also mandatory to have a visual prototype so that the ideas can be easily communicated and understood.&lt;/p&gt;

&lt;p&gt;We decided to carve a niche around &lt;strong&gt;model documentation and testing&lt;/strong&gt;. While tools to build and deploy AI/ML models have flourished and grown, the area of documentation and testing has been mostly neglected. If we could create a solution to improve the documentation and testing process, one that includes the needs and requirements of other stakeholders, we think that it would be a nice complement to the existing model governance ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model documentation
&lt;/h3&gt;

&lt;p&gt;Better documentation is a relatively easily sell - it's something everyone does not really like to do but is required to do. As mentioned previously, teams currently document their findings through various word documents, PowerPoint slides, &lt;code&gt;README.md&lt;/code&gt; files or (gulp) Jupyter Notebook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Iu6q6Vzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/cylynx/verifyml/raw/main/verifyml-workflow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Iu6q6Vzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/cylynx/verifyml/raw/main/verifyml-workflow.png" alt="VerifyML workflow" width="880" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The diagram above maps out the key phases of a machine learning development lifecycle, along with the various pieces of information that should be extracted from the phases and inserted in a model's documentation.&lt;/p&gt;

&lt;p&gt;With VerifyML, we are creating a more structured approach to documentation, one that aligns with the requirements of various stakeholders - product owners, developers and compliance. Documentation is done automatically in a way that the production model and the docs are always in sync. By integrating documentation in a data science workflow, we can automate the creation of boilerplate reports, improve integration with existing tools and make it a collaborative process (rather than a chore).&lt;/p&gt;

&lt;p&gt;We explored various solutions in the machine learning space as well as in the neighbouring software development space for inspiration and learning. Some notable ones include Git and Github, &lt;a href="https://github.com/tensorflow/model-card-toolkit"&gt;Google Model Cards&lt;/a&gt;and &lt;a href="https://aifs360.mybluemix.net/"&gt;IBM's Factsheets&lt;/a&gt;. One of the main design decisions we faced was whether to go with a plain-text git-based solution or a structured schema approach. Eventually, we decided to build on top of Google Model Card (structured protobuf schema). This sacrifices immediate readability of the file, but makes it easy to be processed across different systems in a predictable manner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model testing
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2JDTfN6w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/cylynx/verifyml/raw/main/github-actions.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2JDTfN6w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/cylynx/verifyml/raw/main/github-actions.png" alt="VerifyML Github actions report" width="880" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Model testing is a relatively foreign concept - software development best practices have not really trickled down to applied machine learning. Testing exists mostly at the framework or algorithm developing stage, but not when it comes to developing models on top of these algorithms. To some extent, a train / test split could be regarded as a test, that of robustness to overfitting, but running it as part of a Jupyter Notebook obscures the intent and makes it hard to replicate.&lt;/p&gt;

&lt;p&gt;Our goal over here is to make these test cases more explicit and promote them to first class data objects that should be maintained, just like test suites in a source code. In engineering speak, model tests are &lt;a href="https://en.wikipedia.org/wiki/System_testing"&gt;system tests&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/Acceptance_testing"&gt;acceptance tests&lt;/a&gt; that ensure that the model meets (and continues to meets) certain prescribed specification. For an AI/ML model, this would include measures of model performance as well as additional considerations like robustness and fairness.&lt;/p&gt;

&lt;p&gt;Besides the existing monitoring solution mentioned in the section above, we were also took inspiration from continuous integration and continuous delivery (CI/CD) testing tools like &lt;a href="https://www.jenkins.io/"&gt;Jenkins&lt;/a&gt; and &lt;a href="https://circleci.com/"&gt;Circle CI&lt;/a&gt;, on the engineering front, and existing fairness libraries like &lt;a href="https://github.com/fairlearn/fairlearn"&gt;Microsoft's Fairlearn&lt;/a&gt;  and &lt;a href="https://github.com/Trusted-AI/AIF360"&gt;IMB's Fairness 360&lt;/a&gt;, on the machine learning side of things.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H6yqk1Rb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82jt9vjn8htjxycu6bvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H6yqk1Rb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82jt9vjn8htjxycu6bvh.png" alt="VerifyML subgroup disparity test" width="765" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We decided to create a Python library that provides out of the box test methods for common data science use cases. As a proof of concept, we built the library around binary classification problems. Developing on top of a scikit-learn API proved to be relatively simple and allows us to support most of the existing machine learning Python frameworks. We then focused our efforts on re-framing and re-categorizing the available methods in the fairness literature. Rather than provide more than twenty different metrics which either map to similar concepts or are simply incompatible from a theoretical sense, we let users specify the base metrics that they are interested in comparing and specify an acceptable threshold of deviation.&lt;/p&gt;

&lt;h3&gt;
  
  
  VerifyML architecture and solution overview
&lt;/h3&gt;

&lt;p&gt;In creating the solution, we felt that the synergies of having documentation and testing in a single solution outweighed the complexity of having to develop both parts. Namely, we would be able to create a solution where test results can be synchronized with the documentation, which acts as a source of truth on all details related to the model. This means that docs are not just static reports to be filled at the end of a model building process, but are evolving documentation that iterates through the conception, development and eventual production of the model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ou7eQWxi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/cylynx/verifyml/raw/main/verifyml-dataflow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ou7eQWxi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/cylynx/verifyml/raw/main/verifyml-dataflow.png" alt="VerifyML data flow" width="880" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above diagram outlines the data flow of our framework. Every model that is created is accompanied by a model card. This acts as the a source of truth, where teams can document qualitative and quantiative aspects of the model, including business objectives, performance analysis and fairness considerations. Teams would be able to iterate on the card from the initial project conception to eventual deployment.&lt;/p&gt;

&lt;p&gt;The model card can be easily edited by both business as well as technical users, either through a web form interface or through the Python library. For example, a product owner could fill up the section on the model's objectives through the web form, while a data scientist would update the section on model explainability with the help of the Python library.&lt;/p&gt;

&lt;p&gt;The VerifyML python library also makes it easy to test an existing scikit-learn compatible model and ensure that the current model meets certain standards. Naturally, the test results can also be easily appended to the documentation to complete the cycle.&lt;/p&gt;

&lt;p&gt;We extend Google Model Card by not only supporting the creation of html reports from the python library, but also creating a separate web app for teams to view the results. There's also a comparison view that allows easy comparison between different model runs or model deployments. Since the competition, we have also created a Github Action which automatically parses the model card in every pull request and checks that the model passes all the required test cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Are any of the ideas truly original? I doubt so, but I think we did a good job stitching together various components and making it easy for any company to improve their model documentation and testing processes. Our holistic approach to the problem and the fact that it solves common pain points in the model development lifecycle probably won the votes from the judging panel.&lt;/p&gt;

&lt;p&gt;Interested readers should check out the &lt;a href="https://www.verifyml.com/"&gt;VerifyML website&lt;/a&gt;, &lt;a href="https://docs.verifyml.com/"&gt;docs&lt;/a&gt; or &lt;a href="https://github.com/cylynx/verifyml/"&gt;Github code&lt;/a&gt;. Feel free to create a Github issue and drop any suggestions or feedback over there! VerifyML is proudly open-sourced and created by a small tech startup. I would like to think that more companies are going to see responsible AI as a comparative advantage or requirement and having an ecosystem of solutions that are not controlled by the interests of large tech companies would be key in driving the sector forward. I look forward to improving the user experience and integration with more machine learning tools over the next year, as well as sharing more thoughts in the space.&lt;/p&gt;

</description>
      <category>writing</category>
      <category>datascience</category>
      <category>machinelearning</category>
      <category>python</category>
    </item>
    <item>
      <title>Easy Graph Visualization With Motif</title>
      <dc:creator>Timothy</dc:creator>
      <pubDate>Wed, 28 Jul 2021 14:16:22 +0000</pubDate>
      <link>https://dev.to/timlrx/easy-graph-visualization-with-motif-42dh</link>
      <guid>https://dev.to/timlrx/easy-graph-visualization-with-motif-42dh</guid>
      <description>&lt;p&gt;Motif is a graph viz web app that simplifies analysis and exploration of rich graph datasets. &lt;/p&gt;

&lt;p&gt;Inspired by &lt;a href="https://kepler.gl/"&gt;kepler.gl&lt;/a&gt;, it makes visual discovery on graph datasets accessible to analysts, data scientists and managers.&lt;/p&gt;

&lt;p&gt;It was created to make analysis and exploration of rich graph datasets with numerous node and edge properties easy. With a web interface, we make it easy to share results and analysis.&lt;/p&gt;

&lt;p&gt;In this post, I will highlight the main features of Motif and do a walkthrough showing how we can visualize the Les Misérables dataset!&lt;/p&gt;

&lt;p&gt;Feel free to try it out at &lt;a href="https://demo.cylynx.io"&gt;https://demo.cylynx.io&lt;/a&gt;. If you like the project, give us a star at our &lt;a href="https://github.com/cylynx/motif.gl"&gt;github repo&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Import options
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1x8jjHvA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qcr5v89tc6m321o65t4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1x8jjHvA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qcr5v89tc6m321o65t4p.png" alt="csv import with motif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Motif supports a variety of import options including CSV files (edge lists, or node-and-edge CSVs), JSON files (its native format), Neo4j and it also includes a jupyter notebook integration!&lt;/p&gt;

&lt;p&gt;For more information on using Motif with jupyter notebooks, check out our post on &lt;a href="https://medium.com/cylynx/introducing-pymotif-194c74faceae"&gt;pymotif&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layouts and styling options
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Eh7PC7A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irrmdv6momsyy0o8ay9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Eh7PC7A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irrmdv6momsyy0o8ay9z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A variety of layout options are available including Concentric, Radial, Grid, Sequential, Circular, Force-directed, and fixed coordinates.&lt;/p&gt;

&lt;p&gt;You can also customize the colors and size of the nodes, as well as their labels. This includes mapping a particular node attribute to a color which automatically creates a legend! Similar styling options are available for edge properties as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Filtering and search options
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vee9qaoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c0nh69doennc49x5ht9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vee9qaoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c0nh69doennc49x5ht9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's an explorer without filtering and search options? Like &lt;br&gt;
Kepler.gl, we provide a time filtering bar and different filtering options depending on the filtered property’s data type (string, number or date).&lt;/p&gt;

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

&lt;p&gt;Simply head to &lt;a href="https://demo.cylynx.io"&gt;demo url&lt;/a&gt; to get started and try out the various features outlined in the post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importing Les Misérables
&lt;/h2&gt;

&lt;p&gt;Let's take a look at how we can visualize the Les Misérables dataset. The Les Misérables dataset is included as a sample data so one can simply click on the "Sample Data" tab highlighted blue in the screenshot below, followed by the Les Misérables box, highlighted in green.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8MNStUyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugezsaqgrtzwawxgy86l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8MNStUyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugezsaqgrtzwawxgy86l.png" alt="motif import les mis"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Properties panel and tooltips
&lt;/h2&gt;

&lt;p&gt;We can click on the "Select All" button in the node and edge properties panel to configure the attributes that we would like to see in the tooltips.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j2Qvkuq8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xkg3t6yvkswg6iovf7ca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j2Qvkuq8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xkg3t6yvkswg6iovf7ca.png" alt="motif properties panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Double clicking a node and edge will show the relevant information in a tooltip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring styles
&lt;/h2&gt;

&lt;p&gt;The toolbar on the left provides a list of panels which comes in handy in data exploration and analysis. This includes a layers panel, a styles panel, a filter panel and a search panel. &lt;/p&gt;

&lt;p&gt;Let's switch from the layers panel to the styles panel by clicking on the palette icon 🎨.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5Yf80Pe2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1iidsah9heffl4yxlrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5Yf80Pe2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1iidsah9heffl4yxlrg.png" alt="motif side panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to play around with the numerous styling options available ✨&lt;/p&gt;

&lt;p&gt;In the next section, I will show how we can create a pretty looking visualization that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k5aZui2j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7ofplzlm4bqmtr85ije.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k5aZui2j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7ofplzlm4bqmtr85ije.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use force-directed layout
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Force-directed_graph_drawing"&gt;Force-directed layout&lt;/a&gt; is a good choice and tends to create aesthetically pleasing layouts. &lt;/p&gt;

&lt;p&gt;The math behind it is a little complicated and involves simulating the repulsive forces within an electrically charged system. Check out this &lt;a href="https://www.strong.io/blog/visualizing-graphs-coulomb-simulation"&gt;post&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;Within Motif, the logic has been programmed and all that is required is to change the layout dropdown to force-directed!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yefZRXaA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grd03yq1tuyatsq595aq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yefZRXaA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grd03yq1tuyatsq595aq.png" alt="les mis force directed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a node label
&lt;/h3&gt;

&lt;p&gt;Next, let's label the nodes with the characters’ names. In our dataset, the names are stored in the "id" field. Click on the 'label' dropdown box within 'node styles' and select the "id" property.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aEymruhh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcnhc52n4ia4zdd111rh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aEymruhh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcnhc52n4ia4zdd111rh.png" alt="les mis node label"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Color the nodes based on the ‘group’ field
&lt;/h3&gt;

&lt;p&gt;The nodes have a "group" attribute that was generated by a clustering algorithm. Let's color the nodes based on their grouping.&lt;/p&gt;

&lt;p&gt;To do that, we need to change the 'node color' from 'fixed' to 'legend', followed by choosing the "group" attribute as our variable of choice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dt1HmUXo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1vidpo3piu88r14mv4cp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dt1HmUXo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1vidpo3piu88r14mv4cp.png" alt="les mis node legend"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Saving your masterpiece
&lt;/h3&gt;

&lt;p&gt;That's it! You should have successfully replicated the example. &lt;/p&gt;

&lt;p&gt;To save or take a screenshot of your graph, head back to the layers panel and click on the camera button to take a screenshot, or the save button to download the file in JSON format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6-aNHFZ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yrh1dvmmxynb0qpk8q0h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6-aNHFZ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yrh1dvmmxynb0qpk8q0h.png" alt="screenshot and save with motif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Share the graph via email or slack, and the recipient can simply drag and drop the graph in the import modal to visualize it as you have created!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this post gives you a good introduction to Motif. Would love to see what you can create with the tool as well! If you have any feedback or comments, feel free to leave them here or at our [Github discussions page].(&lt;a href="https://github.com/cylynx/motif.gl/discussions"&gt;https://github.com/cylynx/motif.gl/discussions&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Related content
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://medium.com/cylynx/introducing-pymotif-194c74faceae"&gt;pymotif - Motif with jupyter notebook&lt;/a&gt;&lt;br&gt;
&lt;a href="https://neo4j.brand.live/c/2021nodes-visualization"&gt;motif with Neo4j (Nodes 2021, starts at 1:04:07)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cylynx/motif.gl"&gt;Github repo&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.cylynx.io/motif"&gt;more information&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>showdev</category>
      <category>javascript</category>
      <category>graphs</category>
    </item>
    <item>
      <title>Introducing Motif Graph Visualization Platform</title>
      <dc:creator>Timothy</dc:creator>
      <pubDate>Tue, 13 Apr 2021 10:08:14 +0000</pubDate>
      <link>https://dev.to/timlrx/introducing-motif-graph-visualization-platform-5e3a</link>
      <guid>https://dev.to/timlrx/introducing-motif-graph-visualization-platform-5e3a</guid>
      <description>&lt;p&gt;We just released a demo version of &lt;a href="https://www.cylynx.io/motif"&gt;Motif graph visualization platform&lt;/a&gt;. Feel free to try out the &lt;a href="https://demo.cylynx.io"&gt;demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We created the tool to help analyst and investigators visualize connected data - mainly around blockchain and financial transactions. I think graph visualization solutions should be more accessible to business users and analyst and took Kepler.gl as an inspiration when creating Motif. The idea is to be backend agnostic and let you use your preferred language/tools while speeding up data discovery and collaboration.&lt;/p&gt;

&lt;p&gt;Here are some feature highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Neo4j integration&lt;/li&gt;
&lt;li&gt;Multiple layout options&lt;/li&gt;
&lt;li&gt;Group edges&lt;/li&gt;
&lt;li&gt;Time series filtering&lt;/li&gt;
&lt;li&gt;Filter and search panels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's a jupyter integration on the way as well. Would love to hear your feedback about it and if there's sufficient interest we even plan to open source the graph explorer.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>javascript</category>
      <category>datascience</category>
      <category>discuss</category>
    </item>
    <item>
      <title>A Comparison of Javascript Graph / Network Visualisation Libraries</title>
      <dc:creator>Timothy</dc:creator>
      <pubDate>Thu, 18 Mar 2021 02:55:03 +0000</pubDate>
      <link>https://dev.to/timlrx/a-comparison-of-javascript-graph-network-visualisation-libraries-34a8</link>
      <guid>https://dev.to/timlrx/a-comparison-of-javascript-graph-network-visualisation-libraries-34a8</guid>
      <description>&lt;p&gt;Graph / Network visualisation is a subcategory within the data visualisation space that has grown in popularity over the past few years. There have been emerging use cases to use graphs to understand IoT, social network or transaction data. The growth in the graph database ecosystem has also resulted in a better understanding of the benefits of a graph data representation.&lt;/p&gt;

&lt;p&gt;As part of the development of &lt;a href="https://www.cylynx.io/motif"&gt;Motif, our graph intelligence software&lt;/a&gt;, we evaluated a range of network visualisation solutions to see which tool best fits our use case. In this article, we document our findings on the state of Javascript graph visualisation libraries. This covers both open source and paid libraries. We hope this will be a useful guide for product owners or developers looking to integrate graph visualisation into their application.&lt;/p&gt;

&lt;p&gt;While graph visualisation libraries are often used for diagrammatic drawings such as UML diagrams or mind maps, those areas are out of our focus. Here, we are looking to evaluate libraries for data exploration and investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Javascript?
&lt;/h2&gt;

&lt;p&gt;There are many other graph visualisation libraries available including popular desktop applications like Gephi or Cytoscape, and libraries coupled with programming languages like visualisation packages within igraph and networkx. These software libraries are good for an individual analyst but are hard to integrate into larger product offerings.&lt;/p&gt;

&lt;p&gt;Javascript with its universal browser support is an extremely attractive solution to build an interactive web application. These libraries could easily be integrated into a larger web application or even published as a desktop electron application. While performance might be poorer than native operating systems capabilities, they are more than good enough for most data visualisation needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  List of Libraries
&lt;/h2&gt;

&lt;p&gt;Here’s the list of 8 libraries we shortlisted for our evaluation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;D3&lt;/li&gt;
&lt;li&gt;Keylines / Regraph&lt;/li&gt;
&lt;li&gt;Vis.js&lt;/li&gt;
&lt;li&gt;Sigma.js / Graphology&lt;/li&gt;
&lt;li&gt;Ogma / Linkurious&lt;/li&gt;
&lt;li&gt;G6 / Graphin&lt;/li&gt;
&lt;li&gt;Ngraph / Vivagraph&lt;/li&gt;
&lt;li&gt;React-force-graph&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Evaluation Areas
&lt;/h2&gt;

&lt;p&gt;We identified 3 areas where we are interested in comparing across the different products: performance / rendering engine, algorithms available and out of the box components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rendering Engine
&lt;/h3&gt;

&lt;p&gt;The factor that has the greatest impact on performance is the rendering engine which the underlying framework uses. Yworks, a diagrammatic library SDK provider, has a nice &lt;a href="https://www.yworks.com/blog/svg-canvas-webgl"&gt;comparison&lt;/a&gt; of the 3 rendering methods. Using a 2015 macbook, SVG performance tops gives workable performance until it reaches 2k nodes and 2k edges. Canvas performance reaches the limit at 5k nodes and 5k edges while WebGL is usable until 10k nodes and 11k edges.&lt;/p&gt;

&lt;p&gt;While WebGL is more performant as it leverages the GPU processing power of a machine, it is also harder to work with, which means there tends to be a tradeoff between performance, ease of use and capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algorithms
&lt;/h3&gt;

&lt;p&gt;This refers to the set of available APIs to allow a user to perform a graph operation. This could include layout options, pathfinding algorithms or even network detection algorithms. All these additional functionalities would significantly cut down on the development time required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;Out of the box components that would speed up product development. This could include a time bar filter or a minimap to help a user navigate through the canvas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary Evaluation Matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Licence&lt;/th&gt;
&lt;th&gt;Rendering Engine&lt;/th&gt;
&lt;th&gt;Algorithms&lt;/th&gt;
&lt;th&gt;Components&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;D3&lt;/td&gt;
&lt;td&gt;BSD&lt;/td&gt;
&lt;td&gt;SVG / Canvas&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keylines&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;Canvas / WebGL&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vis.js&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;Canvas&lt;/td&gt;
&lt;td&gt;Middle&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sigma.js&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;Canvas / WebGL&lt;/td&gt;
&lt;td&gt;Middle&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ogma&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;Canvas / WebGL&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G6&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;Canvas&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ngraph&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;WebGL&lt;/td&gt;
&lt;td&gt;Middle&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React-force-graph&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;WebGL&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.cylynx.io/blog/a-comparison-of-javascript-graph-network-visualisation-libraries/"&gt;Detailed comparisons&lt;/a&gt; available at our original post&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Growth Hacking Github - How to Get Github Stars</title>
      <dc:creator>Timothy</dc:creator>
      <pubDate>Wed, 10 Mar 2021 14:53:44 +0000</pubDate>
      <link>https://dev.to/timlrx/growth-hacking-github-how-to-get-github-stars-2446</link>
      <guid>https://dev.to/timlrx/growth-hacking-github-how-to-get-github-stars-2446</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B1TnfgXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3y2lm858u7egkolvj15.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B1TnfgXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3y2lm858u7egkolvj15.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You have written the most impressive package out there, published it as an open-source library on Github but wondering why it is not attracting any interest or getting any Github stars?&lt;/p&gt;

&lt;p&gt;Turns out publishing a good project is only one part of the puzzle. Getting stars fall into the realm of digital marketing, something developers are perhaps not as well informed or acquainted with. In this post, I share how acquiring Github stars can be understood through the lens of a marketing conversion funnel. I provide examples along the way, including a case study of how I get a zero star Github repository to 50 stars in 10 days.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Github stars ⭐?
&lt;/h2&gt;

&lt;p&gt;In Github, users are able to ⭐ other people's repositories (repos), often to indicate that they like the project and also to bookmark it so they can follow its progress. It is one of the most popular metrics used to evaluate the popularity of a project, though there are other measures such as the number of forks or clones. It's the equivalent of a 👍 on Facebook or a 💖 on Twitter.&lt;/p&gt;

&lt;p&gt;As seen in &lt;a href="https://github.com/EvanLi/Github-Ranking"&gt;this Github project ranking by stars&lt;/a&gt;, top starred projects range from popular web development frameworks like Vue and Bootstrap to data science libraries like Tensorflow. Knowledge sharing repositories like freeCodeCamp and other lists of projects (awesome lists) also tend to rank quite highly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you should promote your Github project?
&lt;/h2&gt;

&lt;p&gt;This might seem obvious, but for the developer community promoting your project is probably regarded as the exception rather than the norm. If you are a developer publishing on Github for internal collaboration purposes or if are just after intrinsic satisfaction that is fine. However, I would argue that for most projects where one is looking for user adoption (a startup or portfolio project), the onus is on the developer to publicise their project and get the attention / stars they deserve.&lt;/p&gt;

&lt;p&gt;The alternative is for the project to be consigned to a graveyard of zero-star code repos, buried under the mass of new projects and forgotten for eternity.&lt;/p&gt;

&lt;p&gt;One way to think of self-promotion is as a means of making good projects discoverable. If you are going to spend a significant amount of time and effort to improve on the status quo, odds are, there is someone out there with the same problem, looking for a solution. If she discovers your solution, it would save her hours or days of time. This benefits both the developer and potential users.&lt;/p&gt;

&lt;p&gt;There are also plenty of existing solutions on Github with potentially a much larger user base. Perhaps your solution is really superior to the existing ones? Or solves a pain point in the existing frameworks? Maybe it is beautifully coded and styled? The truth is, no one is going to know the benefits of your project if you are not going to lay it out in front of them.&lt;/p&gt;

&lt;p&gt;Thankfully, there are plenty of channels for you to do so!&lt;/p&gt;

&lt;h2&gt;
  
  
  Github marketing funnel
&lt;/h2&gt;

&lt;p&gt;As defined in Wikipedia, a &lt;a href="https://en.wikipedia.org/wiki/Purchase_funnel"&gt;marketing funnel&lt;/a&gt; is a pathway that illustrates the customer journey towards the purchase of a good or service. How does this relate to Github stars? Substitute customer with developer or potential user and purchase decision with star. To get stars, we need to build awareness and guide the user to star the project (or convert). So let's build a Github marketing funnel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dfn135yV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7g59jksdlu58rkru61lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dfn135yV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7g59jksdlu58rkru61lg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The funnel lays out the user journey from discovery all the way to staring a project.&lt;/p&gt;

&lt;p&gt;At the first stage (awareness), we use social media posts and other channels to build awareness on the project.&lt;/p&gt;

&lt;p&gt;At the second stage (interest), we aim to build up sufficient interest within these posts and get the user to click through to view the repository.&lt;/p&gt;

&lt;p&gt;At the third stage (desire), the contents within the repository should motivate users to want to use the project (view some demo, clone, fork).&lt;/p&gt;

&lt;p&gt;If all goes well the user will click the star button.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/reduxjs/redux-toolkit"&gt;1. Redux Toolkit&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BEdE8eCW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/494/1%2AQMh-twIrmI2NGc4E_xfVaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BEdE8eCW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/494/1%2AQMh-twIrmI2NGc4E_xfVaw.png" alt="redux toolkit logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The official, opinionated, batteries-included toolset for efficient Redux development redux toolkit star history&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oa_v3Ntu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2noebjov2johx0vu4rz4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oa_v3Ntu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2noebjov2johx0vu4rz4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redux is one of the many state management libraries out there and redux toolkit is a relatively new toolkit to significantly simplify the amount of boilerplate required to implement redux in an application with out of the box good defaults settings.&lt;/p&gt;

&lt;p&gt;In a crowded space of state management libraries, and with developers using their favourite solutions out there (many probably using default redux), a significant effort is required to nudge users to check out a new library and try it out in their application.&lt;/p&gt;

&lt;p&gt;It probably would have been buried in the sea of newer options if not for the efforts of &lt;a href="https://github.com/markerikson"&gt;Mark Erikson&lt;/a&gt;, one of the chief maintainers of redux toolkit to continuously popularise the library and answer questions related to it across multiple channels.&lt;/p&gt;

&lt;p&gt;Fun fact, I probably came across his answers more than 10 times before it finally clicked and I decided to give it a try. Each of his posts is informative and gives a different spin on the benefits of the library. Now, I can't imagine going back to vanilla redux.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/huggingface/transformers"&gt;2. Huggingface Transformers&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--49Lg05pm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/huggingface/transformers/master/docs/source/imgs/transformers_logo_name.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--49Lg05pm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/huggingface/transformers/master/docs/source/imgs/transformers_logo_name.png" alt="huggingface transformer logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;State-of-the-art Natural Language Processing for PyTorch and TensorFlow 2.0 huggingface transformers stars&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YYrmVZLO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yr033sr8euzu1uz98nm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YYrmVZLO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yr033sr8euzu1uz98nm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The transformer neural network architecture marked one of the most major advancements in NLP capabilities and outperformed recurrent or convolutional methods that were more popular back in 2017. The Huggingface transformer library is now one of the most popular deep learning NLP packages and widely adopted by data scientist today. It is not the first library that introduced the transformer architecture for NLP, but it provided an easy to use API to prototype and deploy such transformer-based models. Notably, Hugging Face is a for-profit startup going against the tech giants who have similar open-source projects.&lt;/p&gt;

&lt;p&gt;What contributed to its success? The ease of access to state of the art methods in NLP analysis definitely plays a part. Equally important, was its push in getting users to adopt its solution. By creating a strong open source community around its product, it was able to get organic traction from initial users who preached the benefits of the library, in turn attracting more users.&lt;/p&gt;

&lt;p&gt;Winning over the open-source community definitely put it in the sweet spot for investors and helped it to raise $15m in December 2019 to further develop its commercial platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/timlrx/tailwind-nextjs-starter-blog"&gt;3. Tailwind Nextjs Starter Blog&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Es09jOEq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwc0w6a58dgemq3nircr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Es09jOEq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwc0w6a58dgemq3nircr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a Next.js, Tailwind CSS blogging starter template. Comes out of the box configured with the latest technologies to make technical writing a breeze.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MOmaGAlE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bws2svtm8o1d9phtxgue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MOmaGAlE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bws2svtm8o1d9phtxgue.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I started this side project, with the intention of updating my then Hugo blog. Having spent some time on it, I thought it would be a nice experiment to test out some Github SEO ideas into practice.&lt;/p&gt;

&lt;p&gt;It's a good test case because unlike the other previous two repos mentioned, I have very little web presence (less than 50 stars across all my projects). I also have a similar repo, namely, my current blog which is essentially the same starter template with more personalised content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The experiment&lt;/strong&gt;: Let's publicise one of them (the starter blog template) and not mention anything about my existing blog.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result&lt;/strong&gt;: After 10 days of promoting the template, I managed to obtain 50 stars, while the repository that this blog is based on did not receive a single star. The template has also risen organically to more than 100 stars at the time of this post (25 Feb 2021), with no additional efforts on my part to further publicise it.&lt;/p&gt;

&lt;p&gt;The rest of the post covers some strategies and learnings inspired by digital SEO articles as applied to the 10 days of promotional activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know your potential
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sqt15yBk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6dwcymvys7d1jffcv27.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sqt15yBk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6dwcymvys7d1jffcv27.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unless your project is a totally groundbreaking idea with no precedent, one can get a good sense of the maximum potential of stars by referring to other more popular projects in the same category.&lt;/p&gt;

&lt;p&gt;If you are developing a new web framework, your maximum potential stars would be the number of stars that React or Vue has (about 180k as at Feb 2021). If you are writing a state management library for React, maybe redux would be a good indicator.&lt;/p&gt;

&lt;p&gt;For my tailwind nextjs template, I did not want to restrict it to only Nextjs projects using Tailwind CSS but rather look at other blog templates. Other similar templates in my comparison list include &lt;a href="https://github.com/alxshelepenok/gatsby-starter-lumen"&gt;Gatsby Starter Lumen&lt;/a&gt; or &lt;a href="https://github.com/luizdepra/hugo-coder"&gt;Hugo Coder&lt;/a&gt; which tells me that a realistic upper bound for a personal portfolio template project is about 1.5k stars.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know your audience and channels
&lt;/h2&gt;

&lt;p&gt;The first step to get stars is to know your audience or the type of people who would be interested in your project, likely to "star" your project or share it. Unlike, content marketing where you will need to explore Google's search console or do keyword research on Google, it is a simpler task on Github - just pick the most well-known repositories that are most similar to yours.&lt;/p&gt;

&lt;p&gt;From there, you can see the people who are using the repo, raise issues, or submit pull requests. A Google search of the repository is also useful to get an idea of the possible channels to publicise your project, taking the existing more established project as a point of reference.&lt;/p&gt;

&lt;p&gt;In my case, I see popular community blogging platforms like Medium and Dev.to as well as aggregator sites like Jamstack Themes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimise your repository
&lt;/h2&gt;

&lt;p&gt;Once you have identified the outreach channels to publicise your content, you should ensure that your repository contains the necessary materials for success. Otherwise, it is a waste of effort to attract visitors without converting them into stargazers.&lt;/p&gt;

&lt;p&gt;There are existing posts out there that discusses this in more detail. Check out this &lt;a href="https://dev.to/nastyox1/8-concrete-steps-to-get-stars-on-github-355c"&gt;dev.to&lt;/a&gt; post or this &lt;a href="https://www.freecodecamp.org/news/how-my-first-project-won-6000-stars-on-github-in-5-days-6340ec99829e/"&gt;freecodecamp post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's a checklist of Github project essentials and nice to have, inspired by the above posts on the topic and my own personal experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Essentials
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Readme.md&lt;/code&gt; - The readme file is like the landing page of your project. It's the first thing a user will go through and evaluate whether the project fits what she is looking for.&lt;/li&gt;
&lt;li&gt;Add a cover image - As mentioned in one of the reference links: "A good percentage of people will star your project just because it looks good, and not all users will scroll down past the top of your READ-ME, so make the top part as pretty as possible".&lt;/li&gt;
&lt;li&gt;Add a &lt;a href="https://docs.github.com/en/github/building-a-strong-community/adding-a-license-to-a-repository"&gt;licence&lt;/a&gt;, preferably open-source. I think people tend to be more generous towards open source licences as opposed to other stricter licences.&lt;/li&gt;
&lt;li&gt;Add a GitHub description with a demo link to the project- Seeing is understanding and beats reading through a chunk of text.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Nice to Have
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Good docs - It shows the maturity of the project and I think every developer appreciates well maintained, comprehensive documentation.&lt;/li&gt;
&lt;li&gt;Social sharing buttons - These could be badges for easy one-click deployment or shields to display the number of pulls from Docker. For an enterprise project, this adds a level of credibility to the project and allows a user to quickly give it a test run.&lt;/li&gt;
&lt;li&gt;Respond to GitHub issues - For someone evaluating whether to use the project as part of their work, GitHub issues is always one of the first things I check out. It tells me how actively the project is being maintained and how responsive or helpful the development team is in engaging with feedback. For a larger project with already some traction, managing an open source community will make or break the project.&lt;/li&gt;
&lt;li&gt;Add a contributor section in the readme - everyone likes a little appreciation, especially on open source projects. Having a contributor section is a nice touch.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Publicise on various channels and social media
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Aw_Nwbjh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8o799sj5mr0lzuryt5lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Aw_Nwbjh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8o799sj5mr0lzuryt5lg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Share your repository across the various sources you have identified. It definitely helps if you have existing credibility or standing on these channels but otherwise posting your project as a showcase or as a means for discussion is a good way of approaching it.&lt;/p&gt;

&lt;p&gt;For social media, having the right tags also helps to publicise your project especially if you don't have many followers. Tagging the right accounts on Twitter can help amplify the outreach as these accounts tend to reshare posts. Having the right tags also helps disseminate your content to the relevant audience with similar interest.&lt;/p&gt;

&lt;p&gt;Post regularly and across different time zones. With how fast things move on popular forums and Twitter, unless your post gets a lot of traction, it will be buried by other new content. Re-posting the content in various forms is a good way to get different people's interest and posting at different time caters to a range of international audience.&lt;/p&gt;

&lt;p&gt;The goal with multiple publicity channels is to try and get sufficient interest and attention such that others would try out your project, clone it, talk about it or share it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Theory into practice
&lt;/h4&gt;

&lt;p&gt;I applied all these methods while trying to publicise my new blog template. I posted on my Twitter account which started with zero followers but managed to get quite a bit of interested users as the post was re-shared by more popular accounts.&lt;/p&gt;

&lt;p&gt;Similarly, posting on Reddit in r/react and r/webdev brought in more users to check out the Github repository despite my account being brand new. &lt;strong&gt;Tip&lt;/strong&gt;: You should set up a social sharing image for your repository before sharing it on these platforms.&lt;/p&gt;

&lt;p&gt;A nice benefit is that the project was picked by an editor of a popular newsletter which sent a spike of traffic and stars, helping me achieve 50 stars ahead of my 2 weeks targeted plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyse the source of traffic
&lt;/h3&gt;

&lt;p&gt;Google Analytics is one of the top tools in a digital marketing toolkit. The Github equivalent of this (with much less detail, but still important information) is Github Insights. It gives you a 14-day history of stars and clones over time as well as insights on visitors are coming from.&lt;/p&gt;

&lt;p&gt;This is pretty valuable information that could help to refine a content strategy or help to validate the initial hypothesis on channels and interests.&lt;/p&gt;

&lt;p&gt;Here's the clone and visitor trend of my tailwind nextjs repository. The 300 visitor spike in traffic was due to the project being featured in a newsletter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---kf_FYEM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhmx5yc51slfoaqgf7e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---kf_FYEM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhmx5yc51slfoaqgf7e2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's the corresponding referral traffic statistics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L1hJWH_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j60obdutlwy0fq24bwg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L1hJWH_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j60obdutlwy0fq24bwg6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing I noticed is that Github tends to recommend people with similar interests, projects which are trending or are highly starred. That is why it is essential to draw attention outside of Github before Github's recommendation algorithm kicks in, and further recommends more viewers to your repository. This creates a snowball effect.&lt;/p&gt;

&lt;p&gt;Compared to the previous referral statistics, Github is now my top referring site bringing in 140+ views every day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In this post, I discuss how one could adopt digital marketing best practices to promote an open-source project on Github. I outlined some tips in this article including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calculating your star potential&lt;/li&gt;
&lt;li&gt;Researching on the target audience and channels&lt;/li&gt;
&lt;li&gt;Optimising your repository to convert users&lt;/li&gt;
&lt;li&gt;Publicising content&lt;/li&gt;
&lt;li&gt;Using Github Insights like Google Analytics&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I tried these techniques with a brand new project on social accounts with near-zero social media presence and managed to get 50 Github stars in 10 days (more than 100 currently). This validates the ideas I had in publicising open-source projects and jumpstarting users interest in open-source projects.&lt;/p&gt;

&lt;p&gt;I hope to apply it in the near future for a most fascinating project I am working on - and you can bet there will a post about it, so stay tuned! Happy to discuss other strategies to grow a brand new project and learn more about what works for you.&lt;/p&gt;

</description>
      <category>github</category>
      <category>writing</category>
      <category>devjournal</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Tailwind Nextjs Starter Blog v0.1.2</title>
      <dc:creator>Timothy</dc:creator>
      <pubDate>Sun, 14 Feb 2021 14:14:46 +0000</pubDate>
      <link>https://dev.to/timlrx/tailwind-nextjs-starter-blog-2o6k</link>
      <guid>https://dev.to/timlrx/tailwind-nextjs-starter-blog-2o6k</guid>
      <description>&lt;p&gt;Tailwind Nextjs Starter Blog V0.1.2 now comes with a project page.&lt;/p&gt;

&lt;p&gt;Also fixed a few flex bugs on Safari. &lt;/p&gt;

&lt;p&gt;Really enjoying developing on nextjs so far, especially with next/image which makes image optimization pretty straightforward. &lt;br&gt;
The only difficulty is parsing the image dimensions. This is solved over here: &lt;a href="https://github.com/timlrx/tailwind-nextjs-starter-blog/blob/master/lib/img-to-jsx.js" rel="noopener noreferrer"&gt;https://github.com/timlrx/tailwind-nextjs-starter-blog/blob/master/lib/img-to-jsx.js&lt;/a&gt; where I used the &lt;code&gt;image-size&lt;/code&gt; library to get the file dimensions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Feature List&lt;/em&gt;&lt;br&gt;
Tailwind 2.0&lt;br&gt;
Near perfect lighthouse score&lt;br&gt;
Preact in production build&lt;br&gt;
Mobile-friendly view&lt;br&gt;
Light and dark theme&lt;br&gt;
MDX - write JSX in markdown documents!&lt;br&gt;
Server-side syntax highlighting with rehype-prism&lt;br&gt;
Math display supported via KaTeX&lt;br&gt;
Automatic image optimization via next/image&lt;br&gt;
Flexible data retrieval with next-mdx-remote&lt;br&gt;
Support for tags - each unique tag will be its own page&lt;br&gt;
Projects page&lt;br&gt;
SEO friendly with RSS feed, sitemaps and more!&lt;/p&gt;

&lt;p&gt;Here's how the new projects page looks like:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsgiy8ifsgpfng6tk2t18.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsgiy8ifsgpfng6tk2t18.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's how the current blog posts looks like:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmqerzqwjhgqrqxeof7hg.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmqerzqwjhgqrqxeof7hg.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know if you are using the template / planning to use the template and what other features would you like to see!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Introducing Tailwind Nexjs Starter Blog</title>
      <dc:creator>Timothy</dc:creator>
      <pubDate>Sun, 07 Feb 2021 15:22:31 +0000</pubDate>
      <link>https://dev.to/timlrx/introducing-tailwind-nexjs-starter-blog-2po6</link>
      <guid>https://dev.to/timlrx/introducing-tailwind-nexjs-starter-blog-2po6</guid>
      <description>&lt;p&gt;Welcome to my new blog written with &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt;, &lt;a href="https://tailwindcss.com/"&gt;Tailwind CSS&lt;/a&gt;. I have made the blog available as a &lt;a href="https://github.com/timlrx/tailwind-nextjs-starter-blog"&gt;starter template&lt;/a&gt; so feel free to fork and modify to your needs. Comes out of the box configured with the latest technologies to make technical writing a breeze. Easily configurable and customizable. Perfect as a replacement to existing Jekyll and Hugo individual blogs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;I wanted to port my existing blog to Nextjs and Tailwind CSS but there was no easy out of the box template to use so I decided to create one.&lt;/p&gt;

&lt;p&gt;It is inspired by &lt;a href="https://github.com/leerob/leerob.io"&gt;Lee Robinson's blog&lt;/a&gt;, but focuses only on static site generation. Design is adapted from &lt;a href="https://github.com/tailwindlabs/blog.tailwindcss.com"&gt;Tailwindlabs blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I wanted it to be nearly as feature-rich as popular blogging templates like &lt;a href="https://github.com/daattali/beautiful-jekyll"&gt;beautiful-jekyll&lt;/a&gt; and &lt;a href="https://github.com/wowchemy/wowchemy-hugo-modules"&gt;Hugo Academic&lt;/a&gt; but with the best of React's ecosystem and current web development's best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Easy styling customization with &lt;a href="https://blog.tailwindcss.com/tailwindcss-v2"&gt;Tailwind 2.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Near perfect lighthouse score - &lt;a href="https://www.webpagetest.org/result/210111_DiC1_08f3670c3430bf4a9b76fc3b927716c5/"&gt;Lighthouse report&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lightweight, 43kB first load JS, uses Preact in production build&lt;/li&gt;
&lt;li&gt;Mobile-friendly view&lt;/li&gt;
&lt;li&gt;Light and dark theme&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mdxjs.com/"&gt;MDX - write JSX in markdown documents!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Server-side syntax highlighting with &lt;a href="https://github.com/mapbox/rehype-prism"&gt;rehype-prism&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Math display supported via &lt;a href="https://katex.org/"&gt;KaTeX&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Automatic image optimization via &lt;a href="https://nextjs.org/docs/basic-features/image-optimization"&gt;next/image&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Flexible data retrieval with &lt;a href="https://github.com/hashicorp/next-mdx-remote"&gt;next-mdx-remote&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Support for tags - each unique tag will be its own page&lt;/li&gt;
&lt;li&gt;SEO friendly with RSS feed, sitemaps and more!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sample posts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tailwind-nextjs-starter-blog.vercel.app/blog/github-markdown-guide"&gt;A markdown guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwind-nextjs-starter-blog.vercel.app/blog/guide-to-using-images-in-nextjs"&gt;Learn more about images in Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwind-nextjs-starter-blog.vercel.app/blog/deriving-ols-estimator"&gt;A tour of math typesetting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwind-nextjs-starter-blog.vercel.app/blog/pictures-of-canada"&gt;Simple MDX image grid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwind-nextjs-starter-blog.vercel.app/blog/the-time-machine"&gt;Example of long prose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start Guide
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/timlrx/tailwind-nextjs-starter-blog"&gt;Fork Tailwind Nextjs Starter Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rename the project to &lt;code&gt;&amp;lt;yourusername&amp;gt;.github.io&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Modify &lt;code&gt;siteMetadata.json&lt;/code&gt; and blog posts&lt;/li&gt;
&lt;li&gt;Deploy on Vercel&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;p&gt;First, run the development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;span class="c"&gt;# or&lt;/span&gt;
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; with your browser to see the result.&lt;/p&gt;

&lt;p&gt;You can start editing the page by modifying &lt;code&gt;pages/index.js&lt;/code&gt;. The page auto-updates as you edit the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extend / Customize
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;data/siteMetadata.json&lt;/code&gt; - contains most of the site related information which should be modified for a user's need.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;data/logo.svg&lt;/code&gt; - replace with your own logo.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;data/blog&lt;/code&gt; - replace with your own blog posts.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public/static&lt;/code&gt; - store assets such as images and favicons.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;css/tailwind.css&lt;/code&gt; - contains the tailwind stylesheet which can be modified to change the overall look and feel of the site.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;components/social-icons&lt;/code&gt; - to add other icons, simply copy an svg file from &lt;a href="https://simpleicons.org/"&gt;Simple Icons&lt;/a&gt; and map them in &lt;code&gt;index.js&lt;/code&gt;. Other icons uses &lt;a href="https://heroicons.com/"&gt;heroicons&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;components/MDXComponents.js&lt;/code&gt; - pass your own JSX code or React component by specifying it over here. You can then call them directly in the &lt;code&gt;.mdx&lt;/code&gt; or &lt;code&gt;.md&lt;/code&gt; file. By default, a custom link and image component is passed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;layouts&lt;/code&gt; - main templates used in pages.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pages&lt;/code&gt; - pages to route to. Read the &lt;a href="https://nextjs.org/docs"&gt;Next.js documentation&lt;/a&gt; for more information&lt;/p&gt;

&lt;h2&gt;
  
  
  Post
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontmatter
&lt;/h3&gt;

&lt;p&gt;Frontmatter follows &lt;a href="https://gohugo.io/content-management/front-matter/"&gt;Hugo's standards&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Currently 7 fields are supported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;title (required)
date (required)
tags (required, can be empty array)
lastmod (optional)
draft (optional)
summary (optional)
images (optional, if none provided defaults to socialBanner in siteMetadata config)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an example of a post's frontmatter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
title: 'Introducing Tailwind Nexjs Starter Blog'
date: '2021-01-12'
lastmod: '2021-01-18'
tags: ['next-js', 'tailwind', 'guide']
draft: false
summary: 'Looking for a performant, out of the box template, with all the best in web technology to support your blogging needs? Checkout the Tailwind Nextjs Starter Blog template.'
images: ['/static/images/canada/mountains.jpg', '/static/images/canada/toronto.jpg']
---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compose
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;scripts/compose.js&lt;/code&gt; can be used to easily generate a post with pre-filled front matter.&lt;/p&gt;

&lt;p&gt;The first argument is the name of the post and the second optional argument is the extension (default to .mdx)&lt;/p&gt;

&lt;p&gt;Example code to generate the post called "My First Post" in markdown format&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node ./scripts/compose.js "My First Post" .md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate &lt;code&gt;./data/blog/my-first-post.md&lt;/code&gt; with pre-filled front matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Vercel&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The easiest way to deploy the template is to use the &lt;a href="https://vercel.com"&gt;Vercel Platform&lt;/a&gt; from the creators of Next.js. Check out the &lt;a href="https://nextjs.org/docs/deployment"&gt;Next.js deployment documentation&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Netlify / Github Pages / Firebase etc.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
As the template uses &lt;code&gt;next/image&lt;/code&gt; for image optimization, additional configurations has to be made to deploy on other popular static hosting websites like &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt; or &lt;a href="https://pages.github.com/"&gt;Github Pages&lt;/a&gt;. An alternative image optimization provider such as Imgix, Cloudinary or Akamai has to be used. Alternatively, replace the &lt;code&gt;next/image&lt;/code&gt; component with a standard &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag. See &lt;a href="https://nextjs.org/docs/basic-features/image-optimization"&gt;&lt;code&gt;next/image&lt;/code&gt; documentation&lt;/a&gt; for more details.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
