Edward Jackson

Edward Jackson


How to Create a Public File Sharing Service with Vue.js and Node.js

This tutorial explores how to create a public file sharing service with link shortening and file type restriction features with Vue.js, Node.js.

File upload plays an integral part in many web applications. It is used in programs such as email clients, chat applications, commenting systems, among others.

Before JavaScript frameworks dominated web development, file upload systems were similar. These systems usually comprise a form with a file input. After the form is submitted, the backend receives the files, stores them and redirects the user’s page. With the popularity of JavaScript frameworks today, the situation is different. File uploads nowadays can have several features. Some of these are AJAX submissions, progress bars, pause and continue features.

The finished code for this tutorial can be found at these Github repositories:

Application Architecture

In this article, we will be building a public file upload and sharing service. It will have a Node.js-powered backend and a Vue.js-powered frontend. The service will be used anonymously and won’t have any authenticated users. We will submit the file through AJAX and store it in the backend filesystem.

The file meta-data information will be stored in a MongoDB database. All the uploaded files will be listed on the homepage of the application. Upon clicking the name of the file, we will make a request to the backend to download the file. We will also be able to delete files.

We will include a URL-shortener feature in the application to make it easier to share links. This will be achieved by generating a unique hash for each uploaded file. We will also add a mechanism to restrict which file types can be uploaded with the application.

Install and Configure Packages

Before we can install any of the packages, we will need a few things. We must have Node.js installed on our system along with the MongoDB database.

Now that we have a clear understanding of the application requirements, let’s start building it. The application will have a separate backend and frontend. Each will be in a separate folder. Create two folders named client and server in the same directory. Move to the server folder and initialize a new Node.js application with:

npm init  

Accept the default values when prompted. Next, move out of the server folder to the level where both folders reside. Initialize a new Vue.js application with:

vue init webpack client  

Accept the default values as well. When asked to install the router plugin, select yes. Now that we have scaffolded the frontend and backend, let’s install the required packages, starting with the frontend. Move into the client folder and install the Axios.js package using the following command:

npm install --save axios  

Navigate again to the server folder and, install the packages:

npm install --save btoa body-parser express mongoose multer  

Let’s outline the purpose of each of the packages:

List Uploaded Files

Now that the packages are installed, we will list the files from the backend. For now, we do not have any uploaded files yet but we will get to that later. In the server folder, there should be an index.js file. If it is not present, create it. In there, import several libraries by pasting the following:

const bodyParser = require('body-parser');  
const express = require('express');  
const app = express();

app.listen(3000, () => {  
  console.log('Server started on port : ' + 3000);

Start the Node.js server using:

node index.js  

There should be a message in the console without any errors. The message should read:

Server started on port: 3000  

Next, create a file in models/file.js. In there paste in the following:

const mongoose = require('mongoose');  
const Schema = mongoose.Schema;

let FileSchema = new Schema({  
  name: { type: String, required: true, max: 100 },
  encodedName: { type: String, required: false, max: 100, default: null }

module.exports = mongoose.model('file', FileSchema, 'files');  

Here, we are using Mongoose.js to create the model to represent a single file. This is what we will use to query the database for uploaded files. To use it, we only have to import the exported module from the file.

Next, let’s create a service file. This is where our logic for querying the database will be. It will also contain the connection information for the MongoDB database. Still in the server directory, create a file in services/file.service.js. In there, paste the following:

const mongoose = require('mongoose');  
const File = require('../models/file');  
const multer = require('multer');  
const async = require('async')  
const fs = require('fs')  
const path = require('path')  
const btoa = require('btoa')  

In the lines above, we are requiring several libraries. We have also included extra native Node.js libraries: async, fs and path. The function for async is to perform many asynchronous operations. When all operations are complete, we have one success callback. fs is used to create, delete and manipulate local files. Finally, we use path to create folder paths in a safe way depending on the environment.

Let’s now connect to the database and write our method to fetch all uploaded files information in the database. Note that we will only store file information in the database. The physical file itself will be in a folder somewhere in the server. In the same file, paste in the following:

const fileConfig = require('../config/file.config')  
const mongoDB = fileConfig.dbConnection;  
mongoose.connect(mongoDB, { useNewUrlParser: true });  
mongoose.Promise = global.Promise;  

This connects to our database and requires the configuration information for our file service. The file does not exist yet, so let’s create it in config/file.config.js. Paste in the following:

module.exports = {  
  supportedMimes: {
    'text/csv': 'csv'
  uploadsFolder: 'uploads',
  dbConnection: 'mongodb://'

The supportedMimes config will enable us to restrict which file types we will allow for uploads. The keys in the object are the mime types and the values are the file extensions.

The uploadsFolder configuration is used to specify the directory name for uploaded files. It is relative to the server root.

In the dbConnection configuration, we are specifying the connection string for our database. The Mongoose library will create the database if it does not exist.

Finally, let us create a method for querying the files. Paste in the following into our file.service.js file:

module.exports = {  
  getAll: (req, res, next) => {
    File.find((err, files) => {
      if (err) {
        return res.status(404).end();
      console.log('File fetched successfully');

This exports an object with a method called getAll which fetches a list of files from the database. For now, the method only exists but isn’t connected to any route so the frontend has no way of accessing it yet. Let’s build our first route to fetch uploaded files.

Create a route file in routes/api.js. Add in the following:

const express = require('express');  
const router = express.Router();  
const fileService = require('../services/file.service.js');  
const app = express();

router.get('/files', fileService.getAll);  
module.exports = router;  

Before we start the server again, let’s paste the following into index.js:

const apiRoutes = require('./routes/api');  
app.use('/api', apiRoutes);  

Before visiting the route, we need one more step. With our current setup, MongoDB database needs to be running on port 27017. This port is the default port when the server is started without any arguments. To start the server with the default port run the command:


To start it with a specific port, use the command:

mongod --port portnumber  

If you specify a port number, do not forget to update the port number in the config file, config/file.config.js in this line

dbConnection: 'mongodb://'  

Now, the route is ready to serve files from the backend. The registered route will live at the location localhost:3000/api/files. We do not have any files in the backend yet. If we visit the URL in the browser, we will get an empty array response. In the backend console, we should notice a message titled: File fetched successfully.

Do not forget to restart the Node.js server.

Build backend API for receiving files

At this stage, the backend application is able to connect to the database. Next, we will build the route API for receiving one or more files. First, we will only store the file locally. In the file services/file.service.js, alongside the getAll method, add the following:

uploadFile: (req, res, next) => {


This will receive the files but will not insert any information in the database yet. We will get to that in the next chapter.

In routes/api.js, add in the following line before the first route declaration:

const options = fileService.getFileOptions()  
const multer = require('multer')(options);

router.post('/upload', multer.any(), fileService.uploadFile);  

Here, we are including the multer library and providing some options for it. During the upload route declaration:

router.post('/upload', multer.any(), fileService.uploadFile);  

We are specifying the multer library as a middleware. This is so that it will intercept uploaded files and do some filtering for unaccepted files. The options for the library do not exist yet. Let’s add them in a method in the file services/file.service.js. Add in the method below:

getFileOptions: () => {  
  return {
    storage: multer.diskStorage({
      destination: fileConfig.uploadsFolder,
      filename: (req, file, cb) => {
        let extension = fileConfig.supportedMimes[file.mimetype]
        let originalname = file.originalname.split('.')[0]
        let fileName = originalname + '-' + (new Date()).getMilliseconds() + '.' + extension
        cb(null, fileName)
    fileFilter: (req, file, cb) => {
      let extension = fileConfig.supportedMimes[file.mimetype]
      if (!extension) {
        return cb(null, false)
      } else {
        cb(null, true)

This method returns some configuration for filename construction. It will set the destination for the uploaded file. Then it filters files so that we only upload the ones specified in the file config/file.config.js.

We cannot test the upload functionality with our current setup because we have not written the frontend yet. There is a tool called postman. It is designed exactly for that.

Store File meta-data in the database

Currently, the API route for receiving files only stores the file locally. Let’s modify the application so it also stores the file meta-data in the database. In the file services/file.service.js, modify the uploadFile method like below:

uploadFile: (req, res, next) => {  
  let savedModels = []
  async.each(req.files, (file, callback) => {
    let fileModel = new File({
      name: file.filename
    fileModel.save((err) => {
      if (err) {
        return next('Error creating new file', err);
      fileModel.encodedName = btoa(fileModel._id)
      fileModel.save((err) => {
        if (err) {
          return next('Error creating new file', err);
        console.log('File created successfully');
  }, (err) => {
    if (err) {
      return res.status(400).end();
    return res.send(savedModels)

After the multer library stores the files (locally) it will pass the file list to the callback above. The callback will create a unique hash for each file; then, it will store the file’s original name and hashed key in the database.

The async part is necessary because the meta-data insertion happens asynchronously for each file. We want to return a response to the frontend only when all the information has been saved.

Any file which fails the filter test of the multer middleware will not be passed to the uploadFile callback. If no files have been uploaded, we will return an empty array to the frontend. We can then deal with any validation however we wish.

Build Frontend for listing Files

Now let’s add functionality to our frontend so that it can list files from the backend. Navigate to the frontend folder. Start the development server using the command below:

npm run dev  

The frontend application will be running on the URL localhost:8080.

The first thing we need to do is allow the frontend to be able to send AJAX requests to the backend. To allow this during development, in the client root folder, let’s modify the file config/index.js. Modify the proxyTable key to:

proxyTable: {  
  '/api': 'http://localhost:3000',
    '/file': 'http://localhost:3000'

We have covered more details about the above configuration in a previous article, so check that if you’re facing any difficulties.

Let us create a component to list files. This will be responsible for fetching files from the backend. It will also loop over the list of returned files and create many instances of a child component called UploadedFile, which we will create later.

To begin with, create a component in src/components/UploadedFilesList.vue.

In there, paste in the following:

    # Files List



To list files, we are sending a request to the backend when the component is mounted. This is done using Axios.js, an HTTP library for Javascript. The component is initially created with an empty list of files. When the files list data is returned, we add it to the list of files.

Let’s create the UploadedFile component.Create a component file in src/components/UploadedFile.vue. In there, paste in the following:

      {{ file.name }}


All that this component is currently doing is display the file name. The delete button does not currently perform any action but we will get to that later.

Next, let’s configure the router for our application so we can display the list of files.

In the src/router/index.js file, modify the router as shown below:

import Vue from 'vue'  
import Router from 'vue-router'  
import Main from '@/components/Main'

export default new Router({  
  routes: [
      path: '/',
      name: 'Main',
      component: Main

The router is referencing the Main component file which does not exist yet. Let’s create it in src/components/Main.vue. Paste in the following:

    # Anonymous File Uploader System



Delete the existing file src/components/Hello.vue. It was created during the scaffolding stage and we will not need it. Bootup the frontend development server using npm run dev. If there aren’t any files in the backend, the list will be empty. If all goes well, we should see the text:

Files List  

Build Frontend for Uploading Files

At this stage, we can list files from the server. Our next task is to add the ability to upload files.

First, create a component for uploading files in src/components/UploadsContainer.vue. In there, paste the following:

    # Uploader


      Start Upload      
      Cancel Upload


Add it to the dependencies of src/components/Main.vue as shown below. First, let us import it:

import UploadsContainer from '@/components/UploadsContainer'  

Then we list it as a child component:

components: {  

Add a method as shown below:

methods: {  
  filesUploaded(files) {

Then, instantiate it in the template as shown below:

    # Anonymous File Uploader System


In the component src/components/UploadedFilesList.vue, add a method as below:

filesUploaded(files) {  
  files.forEach(file => {

Let us break down what is happening in these components.

Inside src/components/UploadsContainer, we have a file upload input. Attached to it is a changed event handler called fileSelected:


When a file is selected, this handler is fired. The logic in this handler sets the selected files as a property in the component using the following:

let formData = new FormData()

for (let index = 0; index < files.length; index++) {  
  formData.append(name, files[index], files[index].name)

this.$set(this, 'formData', formData)  

This is using HTML5’s native FormData API.

Then we have a submit button:

Start Upload  

This calls a method named startUpload which is responsible for setting the status as actively uploading. Then, it calls another method which sends the formData property, containing the files to the backend.

If the upload was successful, we set the formData to null. Then, we emit an event to the parent container so it can update the uploaded files list using:

updateFilesList (files) {  
  this.$emit("files-uploaded", files)

If an error occurs, we show an alert to the user. We also have a cancel feature which will be triggered by the cancel button below:

Cancel Upload  

And it will only show when an upload process has started. The “start upload” button will only display when there is no upload in progress.

We are binding the form field to a property which specifies the key that will be used when sending files to the server:


The input field will also be hidden when an upload is in progress.

Onto the next file src/components/Main.vue. After instantiating UploadsContainer, we listen to an event using the syntax:


This will receive the uploaded files so we can pass it to a method named filesUploaded in the component src/components/UploadedFilesList.vue. This will make sure the list is updated.

Add support for file download

Frontend download setup

Now that we have the ability to upload files, let’s make sure we can download them.

First, create a component in src/components/FileDownloader.vue.

In there, paste the following:



This component includes an iframe in the template. Anytime the source for the iframe changes, it will make a request to that URL.

In the component src/components/UploadedFile.vue, include the downloader:

import FileDownloader from './FileDownloader'  

Let us register it first:

components: {  

Then we can use it in the template:


Add a method:

downloadFile(event) {  
  let url = event.target.href
  this.downloadKey += 1

  this.$nextTick().then(() => {

Then, modify the link in the template as shown below:

{{ file.name }}  

This generates the appropriate URL by binding to the encodedName property of our file props.

Let’s make sure that the download is triggered on every click. We have to bind the download component’s key to a data property on the parent component.

Add a data property in src/components/UploadedFile.vue:

return {  
  downloadKey: 1

This key is incremented on each click of the download link. This forces the iframe to rerender and hence triggers the download.

Backend download setup

Now, the frontend is ready for making download requests. However, the backend has not been set up to serve the files yet. Let’s set it up now. In the backend file index.js, add the following lines before the call to start the server:

const fileRoute = require('./routes/file');  
app.use('/file', fileRoute);  

Next, create the route file routes/file.js. In there, add the content:

const express = require('express');  
const router = express.Router();  
const fileService = require('../services/file.service.js');  
router.get('/download/:name', fileService.downloadFile);  
module.exports = router;  

This sets up a route which accepts the hashed key of a file as an argument. This argument is then used to fetch the file from the database to get the real name of the file. Then, we reply with a download response.

Let’s set up the method handler for the route. Inside the file services/file.service.js, add a method to the exports as shown:

downloadFile(req, res, next) {  
  File.findOne({ name: req.params.name }, (err, file) => {
    if (err) {

    if (!file) {
      File.findOne({ encodedName: req.params.name }, (err, file) => {
        if (err) {
        if (!file) {

        let fileLocation = path.join(__dirname, '..', 'uploads', file.name)

        res.download(fileLocation, (err) => {
          if (err) {

When we restart the backend server, any file link on the frontend can now be clicked to download that file.

Add Frontend support for deleting files

Finally, let’s add functionality to delete files. Let’s work on the frontend first. In the frontend file src/components/UploadedFile.vue, add the method below:

deleteFile (file) {  
  this.$emit("delete-file", file);

Modify the delete button in the component to the following:


Upon clicking the button, the component emits an event called delete-file to the parent.

Let’s modify the parent component src/components/UploadedFilesList.vue. Modify the UploadFile instantiation to the following:

v-for="file in files"  

In there, we add an event listener for the emitted child event we just made. This in turn calls a method named deleteFile in the parent. Let’s create that method:

deleteFile(file) {  
  if (confirm('Are you sure you want to delete the file?')) {
    axios.delete('/api/files/' + file._id)
      .then(() => {
        let fileIndex = this.files.indexOf(file)
        this.files.splice(fileIndex, 1)
      .catch(() => {
        console.log("Error deleting file")

The frontend is ready to send AJAX requests to the backend.

Let’s set up the backend to receive the request. In the backend file routes/api.js, add the following line just before the export statement:

router.delete('/files/:id', fileService.deleteFile);  

Then, in the file services/file.service.js, add the method below:

deleteFile(req, res, next) {  
  File.findOne({ id: req.params._id }, (err, file) => {
    if (err) {

    if (!file) {

    let fileLocation = path.join(__dirname, '..', 'uploads', file.name)

    fs.unlink(fileLocation, () => {
      File.deleteOne(file, (err) => {
        if (err) {
          return next(err)
        return res.send([])

Now, we can delete files. When we click the delete link, we get an alert to confirm. If we click “ok”, the file is deleted from the backend folder and the information is removed from the database.


That brings us to the end of our article. We created a file upload service which is capable of many file uploads. It enables us to delete the files and we can download the file as well.

This is only a basic upload application. Possible expansions to this application could be advanced validation, upload progress, image preview feature, or multiple file downloads. Hopefully, this brought you some inspiration and ideas.

#node-js #vue-js

What is GEEK

Buddha Community

How to Create a Public File Sharing Service with Vue.js and Node.js
Easter  Deckow

Easter Deckow


PyTumblr: A Python Tumblr API v2 Client



Install via pip:

$ pip install pytumblr

Install from source:

$ git clone https://github.com/tumblr/pytumblr.git
$ cd pytumblr
$ python setup.py install


Create a client

A pytumblr.TumblrRestClient is the object you'll make all of your calls to the Tumblr API through. Creating one is this easy:

client = pytumblr.TumblrRestClient(

client.info() # Grabs the current user information

Two easy ways to get your credentials to are:

  1. The built-in interactive_console.py tool (if you already have a consumer key & secret)
  2. The Tumblr API console at https://api.tumblr.com/console
  3. Get sample login code at https://api.tumblr.com/console/calls/user/info

Supported Methods

User Methods

client.info() # get information about the authenticating user
client.dashboard() # get the dashboard for the authenticating user
client.likes() # get the likes for the authenticating user
client.following() # get the blogs followed by the authenticating user

client.follow('codingjester.tumblr.com') # follow a blog
client.unfollow('codingjester.tumblr.com') # unfollow a blog

client.like(id, reblogkey) # like a post
client.unlike(id, reblogkey) # unlike a post

Blog Methods

client.blog_info(blogName) # get information about a blog
client.posts(blogName, **params) # get posts for a blog
client.avatar(blogName) # get the avatar for a blog
client.blog_likes(blogName) # get the likes on a blog
client.followers(blogName) # get the followers of a blog
client.blog_following(blogName) # get the publicly exposed blogs that [blogName] follows
client.queue(blogName) # get the queue for a given blog
client.submission(blogName) # get the submissions for a given blog

Post Methods

Creating posts

PyTumblr lets you create all of the various types that Tumblr supports. When using these types there are a few defaults that are able to be used with any post type.

The default supported types are described below.

  • state - a string, the state of the post. Supported types are published, draft, queue, private
  • tags - a list, a list of strings that you want tagged on the post. eg: ["testing", "magic", "1"]
  • tweet - a string, the string of the customized tweet you want. eg: "Man I love my mega awesome post!"
  • date - a string, the customized GMT that you want
  • format - a string, the format that your post is in. Support types are html or markdown
  • slug - a string, the slug for the url of the post you want

We'll show examples throughout of these default examples while showcasing all the specific post types.

Creating a photo post

Creating a photo post supports a bunch of different options plus the described default options * caption - a string, the user supplied caption * link - a string, the "click-through" url for the photo * source - a string, the url for the photo you want to use (use this or the data parameter) * data - a list or string, a list of filepaths or a single file path for multipart file upload

#Creates a photo post using a source URL
client.create_photo(blogName, state="published", tags=["testing", "ok"],

#Creates a photo post using a local filepath
client.create_photo(blogName, state="queue", tags=["testing", "ok"],
                    tweet="Woah this is an incredible sweet post [URL]",

#Creates a photoset post using several local filepaths
client.create_photo(blogName, state="draft", tags=["jb is cool"], format="markdown",
                    data=["/Users/johnb/path/to/my/image.jpg", "/Users/johnb/Pictures/kittens.jpg"],
                    caption="## Mega sweet kittens")

Creating a text post

Creating a text post supports the same options as default and just a two other parameters * title - a string, the optional title for the post. Supports markdown or html * body - a string, the body of the of the post. Supports markdown or html

#Creating a text post
client.create_text(blogName, state="published", slug="testing-text-posts", title="Testing", body="testing1 2 3 4")

Creating a quote post

Creating a quote post supports the same options as default and two other parameter * quote - a string, the full text of the qote. Supports markdown or html * source - a string, the cited source. HTML supported

#Creating a quote post
client.create_quote(blogName, state="queue", quote="I am the Walrus", source="Ringo")

Creating a link post

  • title - a string, the title of post that you want. Supports HTML entities.
  • url - a string, the url that you want to create a link post for.
  • description - a string, the desciption of the link that you have
#Create a link post
client.create_link(blogName, title="I like to search things, you should too.", url="https://duckduckgo.com",
                   description="Search is pretty cool when a duck does it.")

Creating a chat post

Creating a chat post supports the same options as default and two other parameters * title - a string, the title of the chat post * conversation - a string, the text of the conversation/chat, with diablog labels (no html)

#Create a chat post
chat = """John: Testing can be fun!
Renee: Testing is tedious and so are you.
John: Aw.
client.create_chat(blogName, title="Renee just doesn't understand.", conversation=chat, tags=["renee", "testing"])

Creating an audio post

Creating an audio post allows for all default options and a has 3 other parameters. The only thing to keep in mind while dealing with audio posts is to make sure that you use the external_url parameter or data. You cannot use both at the same time. * caption - a string, the caption for your post * external_url - a string, the url of the site that hosts the audio file * data - a string, the filepath of the audio file you want to upload to Tumblr

#Creating an audio file
client.create_audio(blogName, caption="Rock out.", data="/Users/johnb/Music/my/new/sweet/album.mp3")

#lets use soundcloud!
client.create_audio(blogName, caption="Mega rock out.", external_url="https://soundcloud.com/skrillex/sets/recess")

Creating a video post

Creating a video post allows for all default options and has three other options. Like the other post types, it has some restrictions. You cannot use the embed and data parameters at the same time. * caption - a string, the caption for your post * embed - a string, the HTML embed code for the video * data - a string, the path of the file you want to upload

#Creating an upload from YouTube
client.create_video(blogName, caption="Jon Snow. Mega ridiculous sword.",

#Creating a video post from local file
client.create_video(blogName, caption="testing", data="/Users/johnb/testing/ok/blah.mov")

Editing a post

Updating a post requires you knowing what type a post you're updating. You'll be able to supply to the post any of the options given above for updates.

client.edit_post(blogName, id=post_id, type="text", title="Updated")
client.edit_post(blogName, id=post_id, type="photo", data="/Users/johnb/mega/awesome.jpg")

Reblogging a Post

Reblogging a post just requires knowing the post id and the reblog key, which is supplied in the JSON of any post object.

client.reblog(blogName, id=125356, reblog_key="reblog_key")

Deleting a post

Deleting just requires that you own the post and have the post id

client.delete_post(blogName, 123456) # Deletes your post :(

A note on tags: When passing tags, as params, please pass them as a list (not a comma-separated string):

client.create_text(blogName, tags=['hello', 'world'], ...)

Getting notes for a post

In order to get the notes for a post, you need to have the post id and the blog that it is on.

data = client.notes(blogName, id='123456')

The results include a timestamp you can use to make future calls.

data = client.notes(blogName, id='123456', before_timestamp=data["_links"]["next"]["query_params"]["before_timestamp"])

Tagged Methods

# get posts with a given tag
client.tagged(tag, **params)

Using the interactive console

This client comes with a nice interactive console to run you through the OAuth process, grab your tokens (and store them for future use).

You'll need pyyaml installed to run it, but then it's just:

$ python interactive-console.py

and away you go! Tokens are stored in ~/.tumblr and are also shared by other Tumblr API clients like the Ruby client.

Running tests

The tests (and coverage reports) are run with nose, like this:

python setup.py test

Author: tumblr
Source Code: https://github.com/tumblr/pytumblr
License: Apache-2.0 license

#python #api 

NBB: Ad-hoc CLJS Scripting on Node.js


Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.


Experimental. Please report issues here.

Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.


Nbb requires Node.js v12 or newer.

How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).


Install nbb from NPM:

$ npm install nbb -g

Omit -g for a local install.

Try out an expression:

$ nbb -e '(+ 1 2 3)'

And then install some other NPM libraries to use in the script. E.g.:

$ npm install csv-parse shelljs zx

Create a script which uses the NPM libraries:

(ns script
  (:require ["csv-parse/lib/sync$default" :as csv-parse]
            ["fs" :as fs]
            ["path" :as path]
            ["shelljs$default" :as sh]
            ["term-size$default" :as term-size]
            ["zx$default" :as zx]
            ["zx$fs" :as zxfs]
            [nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/$ #js ["ls"])

Call the script:

$ nbb script.cljs
#js {:columns 216, :rows 47}
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
$ ls


Nbb has first class support for macros: you can define them right inside your .cljs file, like you are used to from JVM Clojure. Consider the plet macro to make working with promises more palatable:

(defmacro plet
  [bindings & body]
  (let [binding-pairs (reverse (partition 2 bindings))
        body (cons 'do body)]
    (reduce (fn [body [sym expr]]
              (let [expr (list '.resolve 'js/Promise expr)]
                (list '.then expr (list 'clojure.core/fn (vector sym)

Using this macro we can look async code more like sync code. Consider this puppeteer example:

(-> (.launch puppeteer)
      (.then (fn [browser]
               (-> (.newPage browser)
                   (.then (fn [page]
                            (-> (.goto page "https://clojure.org")
                                (.then #(.screenshot page #js{:path "screenshot.png"}))
                                (.catch #(js/console.log %))
                                (.then #(.close browser)))))))))

Using plet this becomes:

(plet [browser (.launch puppeteer)
       page (.newPage browser)
       _ (.goto page "https://clojure.org")
       _ (-> (.screenshot page #js{:path "screenshot.png"})
             (.catch #(js/console.log %)))]
      (.close browser))

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet macro is similar to promesa.core/let.

Startup time

$ time nbb -e '(+ 1 2 3)'
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx this adds another 300ms or so, so for faster startup, either use a globally installed nbb or use $(npm bin)/nbb script.cljs to bypass npx.


NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.


To load .cljs files from local paths or dependencies, you can use the --classpath argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs relative to your current dir, then you can load it via (:require [foo.bar :as fb]). Note that nbb uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar in the namespace name becomes foo_bar in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"

and then feed it to the --classpath argument:

$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]

Currently nbb only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar files will be added later.

Current file

The name of the file that is currently being executed is available via nbb.core/*file* or on the metadata of vars:

(ns foo
  (:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"


Nbb includes reagent.core which will be lazily loaded when required. You can use this together with ink to create a TUI application:

$ npm install ink


(ns ink-demo
  (:require ["ink" :refer [render Text]]
            [reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
  (js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
  [:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))


Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core namespace is included with the let and do! macros. An example:

(ns prom
  (:require [promesa.core :as p]))

(defn sleep [ms]
   (fn [resolve _]
     (js/setTimeout resolve ms))))

(defn do-stuff
   (println "Doing stuff which takes a while")
   (sleep 1000)

(p/let [a (do-stuff)
        b (inc a)
        c (do-stuff)
        d (+ b c)]
  (prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while

Also see API docs.


Since nbb v0.0.75 applied-science/js-interop is available:

(ns example
  (:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1

Most of this library is supported in nbb, except the following:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.


See the examples directory for small examples.

Also check out these projects built with nbb:


See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.



  • babashka >= 0.4.0
  • Clojure CLI >=
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • bb release

Run bb tasks for more project-related tasks.

Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb 
License: EPL-1.0

#node #javascript

Aria Barnes

Aria Barnes


Why use Node.js for Web Development? Benefits and Examples of Apps

Front-end web development has been overwhelmed by JavaScript highlights for quite a long time. Google, Facebook, Wikipedia, and most of all online pages use JS for customer side activities. As of late, it additionally made a shift to cross-platform mobile development as a main technology in React Native, Nativescript, Apache Cordova, and other crossover devices. 

Throughout the most recent couple of years, Node.js moved to backend development as well. Designers need to utilize a similar tech stack for the whole web project without learning another language for server-side development. Node.js is a device that adjusts JS usefulness and syntax to the backend. 

What is Node.js? 

Node.js isn’t a language, or library, or system. It’s a runtime situation: commonly JavaScript needs a program to work, however Node.js makes appropriate settings for JS to run outside of the program. It’s based on a JavaScript V8 motor that can run in Chrome, different programs, or independently. 

The extent of V8 is to change JS program situated code into machine code — so JS turns into a broadly useful language and can be perceived by servers. This is one of the advantages of utilizing Node.js in web application development: it expands the usefulness of JavaScript, permitting designers to coordinate the language with APIs, different languages, and outside libraries.

What Are the Advantages of Node.js Web Application Development? 

Of late, organizations have been effectively changing from their backend tech stacks to Node.js. LinkedIn picked Node.js over Ruby on Rails since it took care of expanding responsibility better and decreased the quantity of servers by multiple times. PayPal and Netflix did something comparative, just they had a goal to change their design to microservices. We should investigate the motivations to pick Node.JS for web application development and when we are planning to hire node js developers. 

Amazing Tech Stack for Web Development 

The principal thing that makes Node.js a go-to environment for web development is its JavaScript legacy. It’s the most well known language right now with a great many free devices and a functioning local area. Node.js, because of its association with JS, immediately rose in ubiquity — presently it has in excess of 368 million downloads and a great many free tools in the bundle module. 

Alongside prevalence, Node.js additionally acquired the fundamental JS benefits: 

  • quick execution and information preparing; 
  • exceptionally reusable code; 
  • the code is not difficult to learn, compose, read, and keep up; 
  • tremendous asset library, a huge number of free aides, and a functioning local area. 

In addition, it’s a piece of a well known MEAN tech stack (the blend of MongoDB, Express.js, Angular, and Node.js — four tools that handle all vital parts of web application development). 

Designers Can Utilize JavaScript for the Whole Undertaking 

This is perhaps the most clear advantage of Node.js web application development. JavaScript is an unquestionable requirement for web development. Regardless of whether you construct a multi-page or single-page application, you need to know JS well. On the off chance that you are now OK with JavaScript, learning Node.js won’t be an issue. Grammar, fundamental usefulness, primary standards — every one of these things are comparable. 

In the event that you have JS designers in your group, it will be simpler for them to learn JS-based Node than a totally new dialect. What’s more, the front-end and back-end codebase will be basically the same, simple to peruse, and keep up — in light of the fact that they are both JS-based. 

A Quick Environment for Microservice Development 

There’s another motivation behind why Node.js got famous so rapidly. The environment suits well the idea of microservice development (spilling stone monument usefulness into handfuls or many more modest administrations). 

Microservices need to speak with one another rapidly — and Node.js is probably the quickest device in information handling. Among the fundamental Node.js benefits for programming development are its non-obstructing algorithms.

Node.js measures a few demands all at once without trusting that the first will be concluded. Many microservices can send messages to one another, and they will be gotten and addressed all the while. 

Versatile Web Application Development 

Node.js was worked in view of adaptability — its name really says it. The environment permits numerous hubs to run all the while and speak with one another. Here’s the reason Node.js adaptability is better than other web backend development arrangements. 

Node.js has a module that is liable for load adjusting for each running CPU center. This is one of numerous Node.js module benefits: you can run various hubs all at once, and the environment will naturally adjust the responsibility. 

Node.js permits even apportioning: you can part your application into various situations. You show various forms of the application to different clients, in light of their age, interests, area, language, and so on. This builds personalization and diminishes responsibility. Hub accomplishes this with kid measures — tasks that rapidly speak with one another and share a similar root. 

What’s more, Node’s non-hindering solicitation handling framework adds to fast, letting applications measure a great many solicitations. 

Control Stream Highlights

Numerous designers consider nonconcurrent to be one of the two impediments and benefits of Node.js web application development. In Node, at whatever point the capacity is executed, the code consequently sends a callback. As the quantity of capacities develops, so does the number of callbacks — and you end up in a circumstance known as the callback damnation. 

In any case, Node.js offers an exit plan. You can utilize systems that will plan capacities and sort through callbacks. Systems will associate comparable capacities consequently — so you can track down an essential component via search or in an envelope. At that point, there’s no compelling reason to look through callbacks.


Final Words

So, these are some of the top benefits of Nodejs in web application development. This is how Nodejs is contributing a lot to the field of web application development. 

I hope now you are totally aware of the whole process of how Nodejs is really important for your web project. If you are looking to hire a node js development company in India then I would suggest that you take a little consultancy too whenever you call. 

Good Luck!

Original Source

#node.js development company in india #node js development company #hire node js developers #hire node.js developers in india #node.js development services #node.js development

Aria Barnes

Aria Barnes


Why is Vue JS the most Preferred Choice for Responsive Web Application Development?

For more than two decades, JavaScript has facilitated businesses to develop responsive web applications for their customers. Used both client and server-side, JavaScript enables you to bring dynamics to pages through expanded functionality and real-time modifications.

Did you know!

According to a web development survey 2020, JavaScript is the most used language for the 8th year, with 67.7% of people choosing it. With this came up several javascript frameworks for frontend, backend development, or even testing.

And one such framework is Vue.Js. It is used to build simple projects and can also be advanced to create sophisticated apps using state-of-the-art tools. Beyond that, some other solid reasons give Vuejs a thumbs up for responsive web application development.

Want to know them? Then follow this blog until the end. Through this article, I will describe all the reasons and benefits of Vue js development. So, stay tuned.

Vue.Js - A Brief Introduction

Released in the year 2014 for public use, Vue.Js is an open-source JavaScript framework used to create UIs and single-page applications. It has over 77.4 million likes on Github for creating intuitive web interfaces.

The recent version is Vue.js 2.6, and is the second most preferred framework according to Stack Overflow Developer Survey 2019.

Every Vue.js development company is widely using the framework across the world for responsive web application development. It is centered around the view layer, provides a lot of functionality for the view layer, and builds single-page web applications.

Some most astonishing stats about Vue.Js:

• Vue was ranked #2 in the Front End JavaScript Framework rankings in the State of JS 2019 survey by developers.

• Approximately 427k to 693k sites are built with Vue js, according to Wappalyzer and BuiltWith statistics of June 2020.

• According to the State of JS 2019 survey, 40.5% of JavaScript developers are currently using Vue, while 34.5% have shown keen interest in using it in the future.

• In Stack Overflow's Developer Survey 2020, Vue was ranked the 3rd most popular front-end JavaScript framework.

Why is Vue.Js so popular?

• High-speed run-time performance
• Vue.Js uses a virtual DOM.
• The main focus is on the core library, while the collaborating libraries handle other features such as global state management and routing.
• Vue.JS provides responsive visual components.

Top 7 Reasons to Choose Vue JS for Web Application Development

Vue js development has certain benefits, which will encourage you to use it in your projects. For example, Vue.js is similar to Angular and React in many aspects, and it continues to enjoy increasing popularity compared to other frameworks.

The framework is only 20 kilobytes in size, making it easy for you to download files instantly. Vue.js easily beats other frameworks when it comes to loading times and usage.

Take a look at the compelling advantages of using Vue.Js for web app development.

#1 Simple Integration

Vue.Js is popular because it allows you to integrate Vue.js into other frameworks such as React, enabling you to customize the project as per your needs and requirements.

It helps you build apps with Vue.js from scratch and introduce Vue.js elements into their existing apps. Due to its ease of integration, Vue.js is becoming a popular choice for web development as it can be used with various existing web applications.

You can feel free to include Vue.js CDN and start using it. Most third-party Vue components and libraries are additionally accessible and supported with the Vue.js CDN.

You don't need to set up node and npm to start using Vue.js. This implies that it helps develop new web applications, just like modifying previous applications.

The diversity of components allows you to create different types of web applications and replace existing frameworks. In addition, you can also choose to hire Vue js developers to use the technology to experiment with many other JavaScript applications.

#2 Easy to Understand

One of the main reasons for the growing popularity of Vue.Js is that the framework is straightforward to understand for individuals. This means that you can easily add Vue.Js to your web projects.

Also, Vue.Js has a well-defined architecture for storing your data with life-cycle and custom methods. Vue.Js also provides additional features such as watchers, directives, and computed properties, making it extremely easy to build modern apps and web applications with ease.

Another significant advantage of using the Vue.Js framework is that it makes it easy to build small and large-scale web applications in the shortest amount of time.

#3 Well-defined Ecosystem

The VueJS ecosystem is vibrant and well-defined, allowing Vue.Js development company to switch users to VueJS over other frameworks for web app development.

Without spending hours, you can easily find solutions to your problems. Furthermore, VueJs lets you choose only the building blocks you need.

Although the main focus of Vue is the view layer, with the help of Vue Router, Vue Test Utils, Vuex, and Vue CLI, you can find solutions and recommendations for frequently occurring problems.

The problems fall into these categories, and hence it becomes easy for programmers to get started with coding right away and not waste time figuring out how to use these tools.

The Vue ecosystem is easy to customize and scales between a library and a framework. Compared to other frameworks, its development speed is excellent, and it can also integrate different projects. This is the reason why most website development companies also prefer the Vue.Js ecosystem over others.

#4 Flexibility

Another benefit of going with Vue.Js for web app development needs is flexibility. Vue.Js provides an excellent level of flexibility. And makes it easier for web app development companies to write their templates in HTML, JavaScript, or pure JavaScript using virtual nodes.

Another significant benefit of using Vue.Js is that it makes it easier for developers to work with tools like templating engines, CSS preprocessors, and type checking tools like TypeScript.

#5 Two-Way Communication

Vue.Js is an excellent option for you because it encourages two-way communication. This has become possible with the MVVM architecture to handle HTML blocks. In this way, Vue.Js is very similar to Angular.Js, making it easier to handle HTML blocks as well.

With Vue.Js, two-way data binding is straightforward. This means that any changes made by the developer to the UI are passed to the data, and the changes made to the data are reflected in the UI.

This is also one reason why Vue.Js is also known as reactive because it can react to changes made to the data. This sets it apart from other libraries such as React.Js, which are designed to support only one-way communication.

#6 Detailed Documentation

One essential thing is well-defined documentation that helps you understand the required mechanism and build your application with ease. It shows all the options offered by the framework and related best practice examples.

Vue has excellent docs, and its API references are one of the best in the industry. They are well written, clear, and accessible in dealing with everything you need to know to build a Vue application.

Besides, the documentation at Vue.js is constantly improved and updated. It also includes a simple introductory guide and an excellent overview of the API. Perhaps, this is one of the most detailed documentation available for this type of language.

#7 Large Community Support

Support for the platform is impressive. In 2018, support continued to impress as every question was answered diligently. Over 6,200 problems were solved with an average resolution time of just six hours.

To support the community, there are frequent release cycles of updated information. Furthermore, the community continues to grow and develop with backend support from developers.

Wrapping Up

VueJS is an incredible choice for responsive web app development. Since it is lightweight and user-friendly, it builds a fast and integrated web application. The capabilities and potential of VueJS for web app development are extensive.

While Vuejs is simple to get started with, using it to build scalable web apps requires professionalism. Hence, you can approach a top Vue js development company in India to develop high-performing web apps.

Equipped with all the above features, it doesn't matter whether you want to build a small concept app or a full-fledged web app; Vue.Js is the most performant you can rely on.

Original source


#vue js development company #vue js development company in india #vue js development company india #vue js development services #vue js development #vue js development companies

Hire Dedicated Node.js Developers - Hire Node.js Developers

If you look at the backend technology used by today’s most popular apps there is one thing you would find common among them and that is the use of NodeJS Framework. Yes, the NodeJS framework is that effective and successful.

If you wish to have a strong backend for efficient app performance then have NodeJS at the backend.

WebClues Infotech offers different levels of experienced and expert professionals for your app development needs. So hire a dedicated NodeJS developer from WebClues Infotech with your experience requirement and expertise.

So what are you waiting for? Get your app developed with strong performance parameters from WebClues Infotech

For inquiry click here: https://www.webcluesinfotech.com/hire-nodejs-developer/

Book Free Interview: https://bit.ly/3dDShFg

#hire dedicated node.js developers #hire node.js developers #hire top dedicated node.js developers #hire node.js developers in usa & india #hire node js development company #hire the best node.js developers & programmers