DEV Community

Cover image for How to build a simple SDK on TypeScript
David Mendoza (He/Him)
David Mendoza (He/Him)

Posted on

How to build a simple SDK on TypeScript

Hey guys, it's been a while since I wrote a tutorial but this one is something I'm actually working on, so I decided to share with you what I learned ❤️.

BTW we are building a small wrapper for Pokeapi

what we will do

  1. Start a node project
  2. Install our dependencies
  3. Setup eslint & prettier
  4. Setup our package.json
  5. Start coding
  6. Setup small project for testing
  7. Let's Publish

Start a node project

So I will assume you at least know how to do this, but if not you have a picture down here:
npm init
You just need an empty folder and run the next command on it

npm init -y
Enter fullscreen mode Exit fullscreen mode

Now I did some changes to my package.json (keywords, author, repo and version) you don't need to make this changes, but take a look at them if you will like to.

{
  "name": "pokeapi",
  "version": "0.1.0",
  "description": "",
  "main": "index.js",
  "scripts": {

  },
  "keywords": [
    "pokemon",
    "api",
    "sdk",
    "typescript",
    "tutorial"
  ],
  "author": "David M.",
  "license": "GPLv3"
}
Enter fullscreen mode Exit fullscreen mode

You will notice scripts is empty 👀 we will fill it later

Install our dependencies

Now we will install one of our dev dependencies

npm install -D typescript
Enter fullscreen mode Exit fullscreen mode

great! now we need another file on our folder root, it's called "tsconfig.json" you can copy the one that I used (below here) or you can generate it with the next command.

./node_modules/.bin/tsc --init
Enter fullscreen mode Exit fullscreen mode

If you decided for this approach just make sure to adjust the declaration and outDir options according to the JSON bellow.

Setting the declaration attribute to true ensures that the compiler generates the respective TypeScript definitions files aside of compiling the TypeScript files to JavaScript files. The outDir parameter defines the output directory as the dist folder.

or just use mine ¯\_(ツ)_/¯

{
  "compilerOptions": {
    "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "strict": true, /* Enable all strict type-checking options. */
    "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "skipLibCheck": true, /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
    "declaration": true,
    "outDir": "./dist",
  }
}
Enter fullscreen mode Exit fullscreen mode

once we have this setup we will need to add some dependencies (this ones may not apply for your sdk)

npm install -S axios
Enter fullscreen mode Exit fullscreen mode

now we are over with our dependencies... for now 👀

Setup eslint and prettier

Eslint

I think this part it's actually the shortest so let's start
you will need to run the next command:

npx eslint --init
Enter fullscreen mode Exit fullscreen mode

Now... I recommend the next answers for the eslint init
Eslint init

Prettier

You need to run the next command

npm install -D prettier eslint-config-prettier eslint-plugin-prettier
Enter fullscreen mode Exit fullscreen mode

After you have all that installed change the content of your .eslintrc.json with this

{
    "env": {
        "es6": true,
        "node": true
    },
    "extends": [
        "airbnb-base",
        "prettier/@typescript-eslint",
        "plugin:prettier/recommended"
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": 11,
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint"
    ],
    "rules": {}
}
Enter fullscreen mode Exit fullscreen mode

and add the file .prettierrc.json with this inside

{
    "printWidth": 100,
    "tabWidth": 2,
    "singleQuote": true,
    "jsxBracketSameLine": true,
    "trailingComma": "es5"
}
Enter fullscreen mode Exit fullscreen mode

Setup our package.json

now that we finally have all the development setup ready we need to modify a bit our package.json so it know it's a TypeScript project

{
  "name": "pokeapi",
  "version": "0.1.0",
  "description": "",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "prepare": "npm run build",
    "build": "tsc"
  },
  "keywords": [
    "pokemon",
    "api",
    "sdk",
    "typescript",
    "tutorial"
  ],
  "author": "David M.",
  "license": "GPLv3",
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^3.9.0",
    "@typescript-eslint/parser": "^3.9.0",
    "eslint": "^7.6.0",
    "eslint-config-airbnb-base": "^14.2.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-prettier": "^3.1.4",
    "prettier": "^2.0.5",
    "typescript": "^3.9.7"
  },
  "dependencies": {
    "axios": "^0.19.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

If you notice, all that we changed is the scripts and added some settings main and types,
remember if you change your outputdir on tsconfig.json change it on your package.json.

Start coding

FINALLY
Let's make a new file called index.ts (on our root)
this is where our SDK will leave, we obviously and separate it on different files and import them but my example is short and simple so I will use the same file for all of it.

First we will import everything

import axios from 'axios';
Enter fullscreen mode Exit fullscreen mode

Let's add some variables we will need

import axios from 'axios';

const API_URL: string = 'https://pokeapi.co/api/v2';
Enter fullscreen mode Exit fullscreen mode

perfect! now that we have "all" setup lets start by adding our first sdk method (getPokemonById)

import axios from 'axios';

const API_URL: string = 'https://pokeapi.co/api/v2';

export function getPokemonById(id: number): Promise<object> {
  return new Promise((resolve, reject) => {
    axios
      .get(`${API_URL}/pokemon/${id}`)
      .then((resp) => {
        resolve(resp.data);
      })
      .catch(reject);
  });
}

export default { getPokemonById };
Enter fullscreen mode Exit fullscreen mode

Finally our code should look something like this, notice that we export our function and as an export default we use "all of our functions" I will add another function so we can have a better idea of multiple functions working from the sdk. It should look like this...

import axios from 'axios';

const API_URL: string = 'https://pokeapi.co/api/v2';

export function getPokemonById(id: number): Promise<object> {
  return new Promise((resolve, reject) => {
    axios
      .get(`${API_URL}/pokemon/${id}`)
      .then((resp) => {
        resolve(resp.data);
      })
      .catch(reject);
  });
}

export function getPokemonTypeById(id: number): Promise<object> {
  return new Promise((resolve, reject) => {
    axios
      .get(`${API_URL}/type/${id}`)
      .then((resp) => {
        resolve(resp.data);
      })
      .catch(reject);
  });
}

export default { getPokemonById, getPokemonTypeById };

Enter fullscreen mode Exit fullscreen mode

Setup small project for testing

Now that we have a really bare bones version of our SDK we will try to use it, but first we should build it!
for simplicity we will make a new node project inside our project like so...

npm run build
mkdir testing
cd testing
npm init -y
npm install ..
Enter fullscreen mode Exit fullscreen mode

now this should make our new project ready to make import our sdk and running it.

my test looked a little like this

const pokeapi = require('pokeapi');

pokeapi.getPokemonById(1).then((pokemon) => {
  console.log(pokemon.name);
});
// it should say "bulbasaur"
Enter fullscreen mode Exit fullscreen mode

Let's Publish

Great to know that you made it until here ❤️
lets start right away!
we will need a new file called .npmignore where we will add all the folders we don't want our sdk to bring with itself like our "testing" folder
it should look like this

testing/
Enter fullscreen mode Exit fullscreen mode

and that should be all for your code ❤️
now the last part is to have an account on Npm do the next commands

npm login #do all the steps necessary
npm publish
Enter fullscreen mode Exit fullscreen mode

and your sdk should be ready to be installed in any other node projects.

Here's some links that you might want:
Npm
Repo

I hope this quick tutorial really helped someone, because I wasn't lucky enough to find one as explicit as this one haha.

Top comments (7)

Collapse
 
sagrawal31 profile image
Shashank Agrawal

Good article. Thanks!

The following line can be removed as it is now merged github.com/prettier/eslint-config-....

'prettier/@typescript-eslint'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
cadrogui profile image
Mikel Carozzi • Edited

Great article, thanks for share. the article does not cover the build of a single file sdk, here are some inputs.

a webpack.config.js file

const path = require('path');

module.exports = {
  mode: "production",
  devtool: "inline-source-map",
  entry: {
    main: "./index.ts",
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: "sdk-file.js",
    library: 'name-of-the-main-class',
    libraryTarget: "umd",
    libraryExport: "default"
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js"],
  },
  module: {
    rules: [
      { 
        test: /\.tsx?$/,
        loader: "ts-loader"
      }
    ]
  }
};
Enter fullscreen mode Exit fullscreen mode

install ts-loader, webpack-cli and npm script for build
build: "webpack"

this work for me and let me build a sdk in a single file.

in the html file dont forget to use

<script type="module"></script>
Enter fullscreen mode Exit fullscreen mode

for include the js file and for the code

Collapse
 
labeebshareef profile image
labeebshareef

getting error:
ReferenceError: FormData is not defined
when added build to testing app
created a package.json file in the dist folder

repo: github.com/labeebshareef/typescrip...

Collapse
 
cerchie profile image
Lucia Cerchie

This is awesome! I'm going to use this with a different API to learn how to build my own. I'm hoping to write my own resources afterward, because you're right, there is a lack of them!

Collapse
 
hairymike profile image
Mike Eller

Great article, thank you!

// Can use npx without having to specify the path now
npx tsc --init
Enter fullscreen mode Exit fullscreen mode
Collapse
 
madeehacareem profile image
madeehacareem

Can we use this sdk for plain javascript project?
Like writing sdk in typescript has support for plain js projects or not?

Collapse
 
christo profile image
cduris

Nice article, it would be greate to cover configuration for baseUrl (to use it in your local/dev/staging env)