Entries by admin

90s Style & Vibrant Lettering Works by Ju Schnee

Original Source: http://feedproxy.google.com/~r/abduzeedo/~3/mVRQXqCAUgc/90s-style-vibrant-lettering-works-ju-schnee

90s Style & Vibrant Lettering Works by Ju Schnee
90s Style & Vibrant Lettering Works by Ju Schnee

AoiroStudioFeb 13, 2020

We are featuring a 90s style lettering work by Ju Schnee, an illustrator based in Berlin, Germany. Each piece from this series kind of reminds you of the era of ‘Fresh Prince of Bel-Air’, it’s hard to deny anything else. Everything is there, the style, colors, quotes and more. Quite lovely if you ask me. After reading Ju’s project blurb, you can’t help to share the same views on the daily challenge that aren’t related to client or work per se. It’s a good challenge to tackle something different each day without any prospectus, real creativity to push its boundaries. Props to Ju!

 

About Ju Schnee

Ju is an illustrator based in Berlin, Germany; living in such a colorful city. It’s no surprises how she gets her inspiration from, make sure to follow her work on Behance.

Personal Site
Behance


5 Pitfalls of User-Generated Content (And How to Avoid Them)

Original Source: https://www.webdesignerdepot.com/2020/02/5-pitfalls-of-user-generated-content-and-how-to-avoid-them/

It brings with it a host of benefits. UGC can greatly increase engagement with websites, as well as shareability and authenticity. Of course, along with benefits are a host of pitfalls, from having to take the time to moderate content, to establishing an engaged community to submit the content in the first place. It’s important to know the pitfalls of user generated content and how they can be avoided. With a clear strategy, and contingency plan in place, it can end up being a very successful and profitable way of driving engagement to a website.

Here are the pitfalls of user-generated content and how to fix them.

1. It Needs To Be Moderated

In an ideal world, all user generated content would stick to the rules and adhere to the site’s standards. Sadly, that’s not the case. Users will upload whatever they like, from inappropriate sites, to offensive words, or totally irrelevant content.

How To Avoid It

Ensure you build in features where content can be moderated. For example, review companies such as TripAdvisor rely on pre-moderation. This means that all reviews which are submitted are sent through a screening process before being put live for everyone to see. This can take a couple of days to sift through depending on the levels of content which has been uploaded, but ensures the site holds its reputation and doesn’t post offensive, random or meaningless content.

You can also implement functions for the UX of a site which means users can report content themselves. This is the system many large companies such as Facebook and Instagram have built in. The pros of this is that content is available instantly for other users to see and engage with but means unwanted content can also get through.

2. People Use It For Their Own Personal Gain

Once user generated content begins to roll in, it can soon increase the site’s popularity, raise the share count, and have numerous benefits. And this will be something others will latch onto. Users can submit their own content for personal gain, rather than that of the site. For example, a competitor could be promoting a service or running a competition and pretend to be a random user to publicise and promote their own products or services.

How To Avoid It

This comes under careful moderation again, but instead of just looking out for offensive or inappropriate content, you look at the context of what has been submitted and whether it’s for personal gain of the contributor. It’s worth adding in code so that any links submitted, automatically default to “no-follow.” Otherwise you’ll have people uploading content purely for a backlink to their own site. Also check the links they are submitting, where they are pointing to and if they are promoting, selling or advertising anything. You can build in a script that picks up certain keywords and blocks them from appearing or flags up certain comments. This can be a useful feature to easily filter through the genuine and the spam content.

3. You Need An Engaged Community To Continuously Generate New Content

It can take a while for a community to become engaged and known enough to submit content. Many companies rely on user generated content as part of their marketing strategy, yet don’t account for the initial time taken to gather loyal readers and contributors. With no users, there will be no user-submitted content. Simple, but true.

How To Avoid It

Get people to know the company and build a loyal following before requesting content. If those wanting to submit something stumble across your site and see it is under-developed, you have hardly any social media followers and no presence, they won’t see the worth in submitting anything. Build a solid base and learn what motivates people to want to submit content and get them excited about joining part of your community. Users want to have their work, ideas and submissions featured on an aesthetically pleasing site that has been well-designed and feels premium. Ensure plenty of thought has gone into the design process of the look of the site, as well as making the user journey to actually submit the content an easy one. People that find the process easy and rewarding will be likely to return and recommend it to others.

4. Copyright Infringement

With an in-house content creation team, submissions usually have to go through a process before they reach publication. They will be checked, assets confirmed as royalty-free and they will have a knowledge of what you can and what you can’t do. By allowing users to submit content you can be opening yourself to a myriad of copyright infringements on everything from duplicate content to image usage.

How To Avoid It

To avoid receiving a hefty copyright infringement lawsuit in your inbox, it’s important you put certain steps into place. With user generated content there are many questions about who is liable for third-party content if it turns out to be false, improper or harmful; unless you make it clear initially, the blame could fall on the website owner. Ensure you have a contract and guidelines in place that stipulates any content users submit is their own responsibility and they are liable should any issues arise. Make guidelines that states images should be royalty-free and available for re-use before they submit them.

5. Unverified Sources Can Damage Website Credibility

When users are free to submit whatever content they like, there is bound to be a fair amount of fake news. You can never really know who every person who submits something is, nor where they are getting their facts and statements from. Negative comments or sources can damage a brand, particularly when other users have no way of knowing if the contributor is trustworthy or not. After all, “If it’s on the internet, it must be true…”

How To Avoid It

Many sites have come across issues with this, with popular social media sites having many users create fake profiles of companies or celebrities. This can be very damaging to a brand and is why it is an idea to have verified users. Twitter and Instagram are known by the well-recognised blue tick which ensures other users know exactly who is posting content. Other sites such as Waze and TripAdvisor award badges to those who are loyal and regular contributors. Not only does this give an incentive to continually contribute, but other users (and moderators) know they are more trustworthy and less likely to post spam or malicious content that could damage the reputation of a site.

 

Featured image via Unsplash.

Source

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

How SEO Can Help Promote Your App

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/Le39t4Ok6Bg/how-seo-can-help-promote-your-app

Those of you who have a basic understanding of SEO might be wondering if I mistyped ASO. SEO is Search Engine Optimization and ASO is App Store Optimization. When we talk about promoting an app, ASO seems more relevant, and so it is. While we can’t deny its importance, SEO can also play a significant […]

The post How SEO Can Help Promote Your App appeared first on designrfix.com.

5 websites to help you learn website design

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/rtfooJVWkpA/5-websites-to-help-you-learn-website-design

Learning to design a professional website is not all complex. In the past, people used to rely on advanced web developers to create a simple website. But things have changed a lot over the past. Think about the simple word press platform. Just by using the basic theme you can easily create a standard website […]

The post 5 websites to help you learn website design appeared first on designrfix.com.

Pokémon fans are losing it over Grand Oak

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/7VKuOKBIL50/grand-oak

The world, it seems, can never have enough Pokémon games. Ever since 1996, Nintendo's been pumping them out on a regular basis; not only have there been far too many standard Pokémon titles over the years for us to count, there have also been assorted spin-off games and mobile apps. That's a lot of Pokémon.

A brand new title, Pokémon Home, has just launched on Nintendo Switch (and also on iOS and Android), and it's already got people talking. This one isn't a game; it's more of a cloud service that enables you to move and trade your Pokémon from various games, but that's not what's got Pokémon fans excited.

Pokémon Fusion revival inspires fan art frenzy

No, the real talking point surrounding Pokémon Home is about an unlikely piece of character design relating to series stalwart, Professor Oak. Oak, we're sure you all know, is a sensible-looking, mild-mannered Pokémon Professor and former trainer who gives you your first starter Pokémon in many of the games. In Pokémon Home, however, there's a new character: Grand Oak. And he's causing quite a buzz.

Professor Oak and Grand Oak

Professor Oak and Grand Oak; spot the difference

While Professor Oak is the sort of person you'd definitely find in the kitchen at parties, Grand Oak is nowhere near as retiring. A self-styled great Pokémon researcher, he looks like Professor Oak might if he had a life-changing experience on holiday in Ibiza and then spent the next six months partying hard and finding himself, man.

Gone are the sensible haircut and lab coat; Grand Oak rocks a pair of killer green shades, a soul patch and the sort of mullet that hasn't been seen in the wild since the late 1980s. The kind of mullet that Pat Sharp or Andre Agassi could only aspire to.

There's no arguing that Grand Oak looks like he means business, and he's definitely on a mission. Within the Pokémon Home story he's the creator of this online system, and he's determined to create the ultimate Pokédex by cataloguing all the Pokémon uploaded to Home. And with his resemblance to one of the 20th century's great scientific minds, who's going to argue?

We just hope his attention doesn't wander. It's not that we doubt his abilities; it just looks like he might have other things on his mind at the moment.

But, you know, as long as he's happy then that's just fine by us.

If you want to hang with Grand Oak then head for the Pokémon Home site. And if you haven't got a Nintendo Switch yet, see today's best deals below.

Related articles:

3 reasons why we're super-excited about Super Nintendo WorldThe 8 best retro gaming consolesSleek new-age Game Boy looks better than the original

Whiteboarding: An effective & modern way to collaborate

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/Sb5hLpM2DEU/whiteboarding-an-effective-modern-way-to-collaborate

Interactive whiteboards have brought a new technological evolution. Their presence is not necessarily new, but recently their advantages in meetings and presentations have come to the forefront of modern businesses.  Over the past decade, interactive whiteboards have witnessed a significant improvement in its adoption within businesses and educational institutions. Today, schools and businesses are utilizing […]

The post Whiteboarding: An effective & modern way to collaborate appeared first on designrfix.com.

How to Create a Physics-based 3D Cloth with Cannon.js and Three.js

Original Source: http://feedproxy.google.com/~r/tympanus/~3/yRIzrJHYskA/

Following my previous experiment where I’ve showed you how to build a 3D physics-based menu, let’s now take a look at how to turn an image into a cloth-like material that gets distorted by wind using Cannon.js and Three.js.

In this tutorial, we’ll assume that you’re comfortable with Three.js and understand the basic principles of the Cannon.js library. If you aren’t, take a look at my previous tutorial about Cannon and how to create a simple world using this 3D engine.

Before we begin, take a look at the demo that shows a concrete example of a slideshow that uses the cloth effect I’m going to explain. The slideshow in the demo is based on Jesper Landberg’s Infinite draggable WebGL slider.

Preparing the DOM, the scene and the figure

I’m going to start with an example from one of my previous tutorials. I’m using DOM elements to re-create the plane in my scene. All the styles and positions are set in CSS and re-created in the canvas with JavaScript. I just cleaned some stuff I don’t use anymore (like the data-attributes) but the logic is still the same:

// index.html
<section class=”container”>
<article class=”tile”>
<figure class=”tile__figure”>
<img src=”path/to/my/image.jpg”
class=”tile__image” alt=”My image” width=”400″
height=”300″ />
</figure>
</article>
</section>

And here we go:

Creating the physics world and update existing stuff

We’ll update our Scene.js file to add the physics calculation and pass the physics World as an argument to the Figure object:

// Scene.js’s constructor
this.world = new C.World();
this.world.gravity.set(0, -1000, 0);

For this example, I’m using a large number for gravity because I’m working with big sized objects.

// Scene.js’s constructor
this.figure = new Figure(this.scene, this.world);

// Scene.js’s update method
this.world.step(1 / 60);

// We’ll see this below!
this.figure.update()

Let’s do some sewing

In the last tutorial on Cannon, I talked about rigid bodies. As its name suggests, you give an entire object a shape that will never be distorted. In this example, I will not use rigid bodies but soft bodies. I’ll create a new body per vertex, give it a mass and connect them to recreate the full mesh. After that, like with the rigid bodies, I copy each Three vertices’ position with Cannon’s body position and voilà!

Let’s start by updating the subdivision segments of the mesh with a local variable “size”: 

const size = 8;

export default class Figure {
constructor(scene, world) {
this.world = world

//…

// Createmesh method
this.geometry = new THREE.PlaneBufferGeometry(1, 1, size, size);

Then, we add a new method in our Figure Class called “CreateStitches()” that we’ll call it just after the createMesh() method. The order is important because we’ll use each vertex coordinate to set the base position of our bodies.

Creating the soft body

Because I’m using a BufferGeometry rather than Geometry, I have to loop through the position attributes array based on the count value. It limits the number of iterations through the whole array and improves performances. Three.js provides methods that return the correct value based on the index.

createStitches() {
// We don’t want a sphere nor a cube for each point of our cloth. Cannon provides the Particle() object, a shape with … no shape at all!
const particleShape = new C.Particle();

const { position } = this.geometry.attributes;
const { x: width, y: height } = this.sizes;

this.stitches = [];

for (let i = 0; i < position.count; i++) {

const pos = new C.Vec3(
position.getX(i) * width,
position.getY(i) * height,
position.getZ(i)
);

const stitch = new C.Body({

// We divide the mass of our body by the total number of points in our mesh. This way, an object with a lot of vertices doesn’t have a bigger mass.
mass: mass / position.count,

// Just for a smooth rendering, you can drop this line but your cloth will move almost infinitely.
linearDamping: 0.8,

position: pos,
shape: particleShape,

// TEMP, we’ll delete later
velocity: new C.Vec3(0, 0, -300)
});

this.stitches.push(stitch);
this.world.addBody(stitch);
}
}

Notice that we multiply by the size of our mesh. That’s because, in the beginning, we set the size of our plane to a size of 1. So each vertex has its coordinates normalized and we have to multiply them afterwards.

Updating the mesh

As we need to set our position in normalized coordinates, we have to divide by the width and height values and set it to the bufferAttribute.

// Figure.js
update() {
const { position } = this.geometry.attributes;
const { x: width, y: height } = this.sizes;

for (let i = 0; i < position.count; i++) {
position.setXYZ(
i,
this.stitches[i].position.x / width,
this.stitches[i].position.y / height,
this.stitches[i].position.z
);
}

position.needsUpdate = true;
}

And voilà! Now you should have a falling bunch of unconnected points. Let’s change that by just setting the first row of our stitches to a mass of zero.

for (let i = 0; i < position.count; i++) {
const row = Math.floor(i / (size + 1));

// …

const stitch = new C.Body({
mass: row === 0 ? 0 : mass / position.count,

// …

I guess you noticed I increased the size plus one. Let’s take a look at the wireframe of our mesh:

As you can notice, when we set the number of segments with the ‘size’ variable, we have the correct number of subdivisions. But we are working on the mesh so we have one more row and column. By the way, if you inspect the count value we used above, we have 81 vertices (9*9), not 64 (8*8).

Connecting everything

Now, you should have a falling bunch of points falling down but not the first line! We have to create a DistanceConstraint from each point to their neighbour.

// createStitches()
for (let i = 0; i < position.count; i++) {
const col = i % (size + 1);
const row = Math.floor(i / (size + 1));

if (col < size) this.connect(i, i + 1);
if (row < size) this.connect(i, i + size + 1);
}

// New method in Figure.js
connect(i, j) {
const c = new C.DistanceConstraint(this.stitches[i], this.stitches[j]);

this.world.addConstraint(c);
}

And tadam! You now have a cloth floating within the void. Because of the velocity we set before, you can see the mesh moves but stops quickly. It’s the calm before the storm.

Let the wind blow

Now that we have a cloth, why not let a bit of wind blow? I’m going to create an array with the length of our mesh and fill it with a direction vector based on the position of my mouse multiplied by a force using simplex noise. Psst, if you have never heard of noise, I suggest reading this article.

We could imagine the noise looking like this image, except where we have angles in each cell, we’ll have a force between -1 and 1 in our case.

https://lramrz.com/2016/12/flow-field-in-p5js/

After that, we’ll add the forces of each cell on their respective body and the update function will do the rest.

Let’s dive into the code!

I’m going to create a new class called Wind in which I’m passing the figure as a parameter.

// First, I’m going to set 2 local constants
const baseForce = 2000;
const off = 0.05;

export default class Wind {
constructor(figure) {
const { count } = figure.geometry.attributes.position;
this.figure = figure;

// Like the mass, I don’t want to have too much forces applied because of a large amount of vertices
this.force = baseForce / count;

// We’ll use the clock to increase the wind movement
this.clock = new Clock();

// Just a base direction
this.direction = new Vector3(0.5, 0, -1);

// My array
this.flowfield = new Array(count);

// Where all will happen!
this.update()
}
}

update() {
const time = this.clock.getElapsedTime();

const { position } = this.figure.geometry.attributes;
const size = this.figure.geometry.parameters.widthSegments;

for (let i = 0; i < position.count; i++) {
const col = i % (size + 1);
const row = Math.floor(i / (size + 1));

const force = (noise.noise3D(row * off, col * off, time) * 0.5 + 0.5) * this.force;

this.flowfield[i] = this.direction.clone().multiplyScalar(force);
}
}

The only purpose of this object is to update the array values with noise in each frame so we need to amend Scene.js with a few new things.

// Scene.js
this.wind = new Wind(this.figure.mesh);

// …

update() {
// …
this.wind.update();
this.figure.update();
// …
}

And before continuing, I’ll add a new method in my update method after the figure.update():

this.figure.applyWind(this.wind);

Let’s write this new method in Figure.js:

// Figure.js constructor
// To help performance, I will avoid creating a new instance of vector each frame so I’m setting a single vector I’m going to reuse.
this.bufferV = new C.Vec3();

// New method
applyWind(wind) {
const { position } = this.geometry.attributes;

for (let i = 0; i < position.count; i++) {
const stitch = this.stitches[i];

const windNoise = wind.flowfield[i];
const tempPosPhysic = this.bufferV.set(
windNoise.x,
windNoise.y,
windNoise.z
);

stitch.applyForce(tempPosPhysic, C.Vec3.ZERO);
}
}

Congratulation, you have created wind, Mother Nature would be proud! But the wind blows in the same direction. Let’s change that in Wind.js by updating our direction with the mouse position.

window.addEventListener(“mousemove”, this.onMouseMove.bind(this));

onMouseMove({ clientX: x, clientY: y }) {
const { innerWidth: W, innerHeight: H } = window;

gsap.to(this.direction, {
duration: 0.8,
x: x / W – 0.5,
y: -(y / H) + 0.5
});
}

Conclusion

I hope you enjoyed this tutorial and that it gave you some ideas on how to bring a new dimension to your interaction effects. Don’t forget to take a look at the demo, it’s a more concrete case of a slideshow where you can see this effect in action. 

Don’t hesitate to let me know if there’s anything not clear, feel free to contact me on Twitter @aqro.

Cheers!

How to Create a Physics-based 3D Cloth with Cannon.js and Three.js was written by Arno Di Nunzio and published on Codrops.

10 Online Courses To Become A Better Web Designer

Original Source: http://feedproxy.google.com/~r/1stwebdesigner/~3/NujbkXWxTs4/

Whether you’re first entering the world of web design or own a well-established agency, one thing applies to all: you can always learn more. That’s what makes online courses so fabulous. You can learn at your own pace and pick and choose the topics you want to delve deeper into.

Instead of having to hunt around for great web design courses to take, we’ve put together a list of some of our favorite online courses. Each of the following will help you to become a more solid web designer, expand your skill set, and/or improve your business direction.

Your Web Designer Toolbox

Unlimited Downloads: 500,000+ Web Templates, Icon Sets, Themes & Design Assets


DOWNLOAD NOW

UX & Web Design Master Course: Strategy, Design, Development

UX & Web Design Master Course: Strategy, Design, Development - online courses

Become a real expert in web design by taking this master course on Udemy. Instructor Joe Natoli walks you through UX principles for creating better web designs that work for visitors and customers.

Ultimate Web Designer & Developer Course: Build 23 Projects!

Ultimate Web Designer & Developer Course: Build 23 Projects! - online courses

Here’s another great course on Udemy. The instructor this time is Brad Hussey and he breaks down all the details of what it takes to become a full-stack developer. This covers it all from front-end design to back-end programming.

Web Design for Beginners: Real World Coding in HTML & CSS

Web Design for Beginners: Real World Coding in HTML & CSS - online courses

If you’re new to the world of web design, you’ll greatly benefit from this web design for beginners course by Brad Schiff. It shows you how to create HTML5, CSS3, and responsive design in real-world examples.

Grow Your Web Design Skills

Grow Your Web Design Skills - online courses

This fantastic online course on Pluralsight is an obvious choice for expanding your web design skills.

User Experience for Web Design

User Experience for Web Design - online courses

Another course you might want to consider is this breakdown of user experience in web design put together by Chris Nodder. It’s just under two hours long and aimed at beginners, but even pros could use a refresher now and then.

Introduction to Web Design and Development

Introduction to Web Design and Development - online courses

Here’s another beginner-level course, this time a full intro to web design and development. It consists of about three and a half hours of instruction that offer in-depth exploration of topics you need to know to advance your skills.

Web Design: Efficient Workflow

Web Design: Efficient Workflow

For creating a better workflow for running a web design agency or business, this mini-course is a sure bet.

Creating a Responsive Web Design: Advanced Techniques

Creating a Responsive Web Design: Advanced Techniques

Responsive design is a must nowadays. Learn more than just the basics here in this just-over-an-hour long advanced course.

Careers in Web Design and Development

Careers in Web Design and Development

If you’re interested in the business side of things, you won’t want to miss this course all about careers in web design and development.

Treehouse: Front End Web Development

Treehouse: Front End Web Development

The last course on this list is one from Treehouse. It focuses exclusively on front-end web development and covers HTML, CSS, Javascript, and more.

Expand Your Web Design Education

Hopefully you now have the tools at your disposal to further your web design education. Completing the above ten online courses will further your skills and help you take the next step in your career. Be sure to also check out our extensive library of tutorials to add to your toolbox. Best of luck in the effort!

Cover photo courtesy of ShotStash


Motion & Production for "We Need To Talk" Opening Sequence

Original Source: http://feedproxy.google.com/~r/abduzeedo/~3/7tu2gLw6MJs/motion-production-we-need-talk-opening-sequence

Motion & Production for “We Need To Talk” Opening Sequence

AoiroStudioFeb 10, 2020

A couple of months ago, we have shared on ABDZ a very outstanding tribute for the cult AKIRA animated movie by Ash Thorp in collaboration with zaoeyo. zaoeyo has administered to introduce a new project and it’s a motion & production for “We Need To Talk” opening sequence. You can totally feel the inspirational vibes from Blade Runner, Mr. Robot and neons! I am totally digging this visual entrance, especially when it’s used for an opening sequence. Make sure to check out his Behance for more.

WE NEED TO TALK is a documentary directed by Ricky Staub. Last year, I’m glad to have the chance making full-CG sequence for this documentary and it’s my first full solo production commercial opening sequence in my career, and I am very thankful that the director gave me the chance and let me do my things!

About zaoeyo

zaoeyo is a self-taught Visual Designer currently based in Xiangtan from the Hunan province. He focuses most of his work in 3D visuals, motion design and title design.

Behance
Credits

Client: NeighborhoodFilmCompany
Director: Ricky Staub
Solo Production: zaoeyo (xiaolin zeng)
Fluid Vfx: shuifx


Build a JavaScript Command Line Interface (CLI) with Node.js

Original Source: https://www.sitepoint.com/javascript-command-line-interface-cli-node-js/?utm_source=rss

Build a JavaScript Command Line Interface (CLI) with Node.js

As great as Node.js is for “traditional” web applications, its potential uses are far broader. Microservices, REST APIs, tooling, working with the Internet of Things and even desktop applications: it’s got your back.

Another area where Node.js is really useful is for building command-line applications — and that’s what we’re going to be doing in this article. We’re going to start by looking at a number of third-party packages designed to help work with the command line, then build a real-world example from scratch.

What we’re going to build is a tool for initializing a Git repository. Sure, it’ll run git init under the hood, but it’ll do more than just that. It will also create a remote repository on GitHub right from the command line, allow the user to interactively create a .gitignore file, and finally perform an initial commit and push.

As ever, the code accompanying this tutorial can be found on our GitHub repo.

Build a Node CLI

Why Build a Command-line Tool with Node.js?

Before we dive in and start building, it’s worth looking at why we might choose Node.js to build a command-line application.

The most obvious advantage is that, if you’re reading this, you’re probably already familiar with it — and, indeed, with JavaScript.

Another key advantage, as we’ll see as we go along, is that the strong Node.js ecosystem means that among the hundreds of thousands of packages available for all manner of purposes, there are a number which are specifically designed to help build powerful command-line tools.

Finally, we can use npm to manage any dependencies, rather than have to worry about OS-specific package managers such as Aptitude, Yum or Homebrew.

Tip: that isn’t necessarily true, in that your command-line tool may have other external dependencies.

What We’re Going to Build: ginit

Ginit, our Node CLI in action

For this tutorial, we’re going to create a command-line utility which I’m calling ginit. It’s git init, but on steroids.

You’re probably wondering what on earth that means.

As you no doubt already know, git init initializes a Git repository in the current folder. However, that’s usually only one of a number of repetitive steps involved in the process of hooking up a new or existing project to Git. For example, as part of a typical workflow, you may well:

initialize the local repository by running git init
create a remote repository, for example on GitHub or Bitbucket — typically by leaving the command line and firing up a web browser
add the remote
create a .gitignore file
add your project files
commit the initial set of files
push up to the remote repository.

There are often more steps involved, but we’ll stick to those for the purposes of our app. Nevertheless, these steps are pretty repetitive. Wouldn’t it be better if we could do all this from the command line, with no copy-pasting of Git URLs and such like?

So what ginit will do is create a Git repository in the current folder, create a remote repository — we’ll be using GitHub for this — and then add it as a remote. Then it will provide a simple interactive “wizard” for creating a .gitignore file, add the contents of the folder and push it up to the remote repository. It might not save you hours, but it’ll remove some of the initial friction when starting a new project.

With that in mind, let’s get started.

The Application Dependencies

One thing is for certain: in terms of appearance, the console will never have the sophistication of a graphical user interface. Nevertheless, that doesn’t mean it has to be plain, ugly, monochrome text. You might be surprised by just how much you can do visually, while at the same time keeping it functional. We’ll be looking at a couple of libraries for enhancing the display: chalk for colorizing the output and clui to add some additional visual components. Just for fun, we’ll use figlet to create a fancy ASCII-based banner, and we’ll also use clear to clear the console.

In terms of input and output, the low-level Readline Node.js module could be used to prompt the user and request input, and in simple cases is more than adequate. But we’re going to take advantage of a third-party package which adds a greater degree of sophistication — Inquirer. As well as providing a mechanism for asking questions, it also implements simple input controls: think radio buttons and checkboxes, but in the console.

We’ll also be using minimist to parse command-line arguments.

Here’s a complete list of the packages we’ll use specifically for developing on the command line:

chalk — colorizes the output
clear — clears the terminal screen
clui — draws command-line tables, gauges and spinners
figlet — creates ASCII art from text
inquirer — creates interactive command-line user interface
minimist — parses argument options
configstore — easily loads and saves config without you having to think about where and how.

Additionally, we’ll also be using the following:

@octokit/rest — a GitHub REST API client for Node.js
@octokit/auth-basic — an implementation of one of GitHub’s authentication strategies
lodash — a JavaScript utility library
simple-git — a tool for running Git commands in a Node.js application
touch — a tool for implementing the Unix touch command.

Getting Started

Although we’re going to create the application from scratch, don’t forget that you can also grab a copy of the code from the repository which accompanies this article.

Create a new directory for the project. You don’t have to call it ginit, of course:

mkdir ginit
cd ginit

Create a new package.json file:

npm init -y

And edit it to look like so:

{
“name”: “ginit”,
“version”: “1.0.0”,
“description”: “‘git init’ on steroids”,
“main”: “index.js”,
“scripts”: {
“test”: “echo “Error: no test specified” && exit 1″
},
“keywords”: [
“Git”,
“CLI”
],
“author”: “<YOUR NAME>”,
“license”: “ISC”
}

Now install the dependencies:

npm install chalk clear clui figlet inquirer minimist configstore @octokit/rest @octokit/auth-basic lodash simple-git touch

Now create an index.js file in the same folder and require the following dependencies:

const chalk = require(‘chalk’);
const clear = require(‘clear’);
const figlet = require(‘figlet’);

Adding Some Helper Methods

We’re going to create a lib folder where we’ll split our helper code into modules:

files.js — basic file management
inquirer.js — command-line user interaction
github.js — access token management
repo.js — Git repository management.

Let’s start with lib/files.js. Here, we need to:

get the current directory (to get a default repo name)
check whether a directory exists (to determine whether the current folder is already a Git repository by looking for a folder named .git).

This sounds straightforward, but there are a couple of gotchas to take into consideration.

Firstly, you might be tempted to use the fs module’s realpathSync method to get the current directory:

path.basename(path.dirname(fs.realpathSync(__filename)));

This will work when we’re calling the application from the same directory (for example, using node index.js), but bear in mind that we’re going to be making our console application available globally. This means we’ll want the name of the directory we’re working in, not the directory where the application resides. For this purpose, it’s better to use process.cwd:

path.basename(process.cwd());

Secondly, the preferred method of checking whether a file or directory exists keeps changing. The current way is to use existsSync. This returns true if the path exists, false otherwise.

Finally, it’s worth noting that when you’re writing a command-line application, using the synchronous version of these sorts of methods is just fine.

Putting that all together, let’s create a utility package in lib/files.js:

const fs = require(‘fs’);
const path = require(‘path’);

module.exports = {
getCurrentDirectoryBase: () => {
return path.basename(process.cwd());
},

directoryExists: (filePath) => {
return fs.existsSync(filePath);
}
};

Go back to index.js and ensure you require the new file:

const files = require(‘./lib/files’);

With this in place, we can start developing the application.

Initializing the Node CLI

Now let’s implement the start-up phase of our console application.

In order to demonstrate some of the packages we’ve installed to enhance the console output, let’s clear the screen and then display a banner:

// index.js

clear();

console.log(
chalk.yellow(
figlet.textSync(‘Ginit’, { horizontalLayout: ‘full’ })
)
);

You can run the application using node index.js. The output from this is shown below.

The welcome banner on our Node CLI, created using Chalk and Figlet

Next up, let’s run a simple check to ensure that the current folder isn’t already a Git repository. That’s easy: we just check for the existence of a .git folder using the utility method we just created:

//index.js

if (files.directoryExists(‘.git’)) {
console.log(chalk.red(‘Already a Git repository!’));
process.exit();
}

Tip: notice we’re using the chalk module to show a red-colored message.

The post Build a JavaScript Command Line Interface (CLI) with Node.js appeared first on SitePoint.