diff --git a/README.md b/README.md
index c1f361c25dc9938b287826b2e1224e85a078f3f0..ab2535e23693a10d670ea78e47cc7910f680dce6 100644
--- a/README.md
+++ b/README.md
@@ -69,13 +69,18 @@ go mod tidy
 If go.mod and go.sum are missing from the cloned repository, then:
 ```
 # go mod init [module-path]
-go mod init main
+go mod init 0xacab.org/leap/vpn-hole/vpnhole
 ``` 
 
 ## Build & Run <a name="Build & Run"></a>
-
+To build the library and use it as a standalone:
 ```
+# navigate to app/vpnhole
+
+cd app/vpnhole
+
 # build the library
+
 go build
 ```
 An executable binary file would be generated for the library.
@@ -107,10 +112,10 @@ sudo systemctl disable systemd-resolved
 To disable it permanently, uncomment and change `DNSStubListener` to *no* in `/etc/systemd/resolved.conf`; you can revert back everything to default if you stop using the vpn-hole library as a standalone.
 Also stop any other service which prevents from listening on port 53. Then, you can simply execute the binary file.
 
-In **Windows**, an executable named- main.exe would be created. 
+In **Windows**, an executable named- vpnhole.exe would be created. 
 ```
 # executing the binary
-main.exe
+vpnhole.exe
 ```
 This would start the network wide DNS-level blocker on port 53.
 
@@ -134,12 +139,30 @@ Addresses:  ::
 ## Integration <a name="Integration"></a>
 To integrate the VPN-Hole Library with existing cross-platform applications, we will be using gomobile to compile and bind it.
 ```
+# For binding with Android Platforms:
+
+cd vpn-hole/vpnhole
+
+# use gomobile to generate .aar:
+
+gomobile bind -target='android' -o path/for/the/output/filename.aar -v path/for/vpnhole.go
+
+For example: 
+# Here pwd is path/vpn-hole/vpnhole
+
+gomobile bind -target='android' -o vpn-hole.aar -v
+
+# Similarly, GoMobile can be used to compile for other platforms like iOS (XCode is required):
+
+gomobile bind -target='ios' -o path/for/the/output/filename.framework -v path/for/vpnhole.go
 
 ```
 
 ### Adapting to Bitmask_core <a name="Adapting to Bitmask_core"></a>
 ```
 
+
+
 ```
 
 ## License <a name="License"></a>
diff --git a/blacklist.go b/app/vpnhole/blocklist.go
similarity index 50%
rename from blacklist.go
rename to app/vpnhole/blocklist.go
index 1c2ae6fc0a9337486cabfe7aadbb4f63fc5bc6af..5da5f8d914c3f024d6d0feb8a6c032337f6b8845 100644
--- a/blacklist.go
+++ b/app/vpnhole/blocklist.go
@@ -1,14 +1,18 @@
 package main
 
 import (
+	"net/http"
 	"strings"
-	"main/blacklist"
+	"time"
+
+	"0xacab.org/leap/vpn-hole/blacklist"
 	"github.com/miekg/dns"
 )
 
-var privBlacklist = blacklist.New(httpClient)
+var httpClient = &http.Client{Timeout: 30 * time.Second}
+var PrivBlacklist = blacklist.New(httpClient)
 
-func isBlacklisted(req *dns.Msg) bool {
+func IsBlacklisted(req *dns.Msg) bool {
 	if req.Opcode != dns.OpcodeQuery {
 		return false
 	}
@@ -26,5 +30,5 @@ func isBlacklisted(req *dns.Msg) bool {
 		return false
 	}
 
-	return privBlacklist.Contains(strings.TrimRight(q.Name, "."))
+	return PrivBlacklist.Contains(strings.TrimRight(q.Name, "."))
 }
diff --git a/handler.go b/app/vpnhole/handler.go
similarity index 60%
rename from handler.go
rename to app/vpnhole/handler.go
index 1d214ee5e3ddd95b1d4282faecb771a9fb17b7f7..20c1d8683aca38e8b7745126ba0e44ff78f96a2a 100644
--- a/handler.go
+++ b/app/vpnhole/handler.go
@@ -5,41 +5,41 @@ import (
 	"log"
 	"net"
 
+	"0xacab.org/leap/vpn-hole/vpnhole/vpnhole"
 	"github.com/miekg/dns"
 )
 
 var (
-	client   dns.Client
-	upstream string
+	client dns.Client
 
 	blockIPv4 = net.ParseIP("0.0.0.0")
 	blockIPv6 = net.ParseIP("0:0:0:0:0:0:0:0")
 	blockTTL  = uint32(60)
 )
 
-func handler(rw dns.ResponseWriter, req *dns.Msg) {
+func Handler(rw dns.ResponseWriter, req *dns.Msg) {
 	defer rw.Close()
 
-	if isBlacklisted(req) {
-		if err := block(rw, req); err != nil {
-			log.Println(fmt.Errorf("Failed to block request: %w", err))
+	if IsBlacklisted(req) {
+		if err := Block(rw, req); err != nil {
+			log.Println(fmt.Errorf("failed to block request: %w", err))
 		}
 
 		return
 	}
-
-	resp, _, err := client.Exchange(req, upstream)
+	c := alter.ParseFlags()
+	resp, _, err := client.Exchange(req, c.Upstream)
 	if err != nil {
-		log.Fatalln(fmt.Errorf("Failed to exchange: %w", err))
+		log.Fatalln(fmt.Errorf("failed to exchange: %w", err))
 		return
 	}
 
 	if err = rw.WriteMsg(resp); err != nil {
-		log.Println(fmt.Errorf("Failed to reply: %w", err))
+		log.Println(fmt.Errorf("failed to reply: %w", err))
 	}
 }
 
-func block(rw dns.ResponseWriter, req *dns.Msg) error {
+func Block(rw dns.ResponseWriter, req *dns.Msg) error {
 	resp := &dns.Msg{}
 	resp.SetReply(req)
 
diff --git a/app/vpnhole/main.go b/app/vpnhole/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..8af4c67c70d6e3ed62ab923d2bd382b3bcbdfc50
--- /dev/null
+++ b/app/vpnhole/main.go
@@ -0,0 +1,57 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"log"
+
+	"0xacab.org/leap/vpn-hole/vpnhole/vpnhole"
+	"github.com/miekg/dns"
+
+	"time"
+)
+
+func init() {
+	// start the cmdline parser
+	alter.ParseFlags()
+
+}
+
+func main() {
+
+	// call ParseFlags() to get the config struct with the values
+	c := alter.ParseFlags()
+	fmt.Println(c)
+
+	// start the vpnhole
+	if err := c.Start(); err != nil {
+		log.Fatalln(fmt.Errorf("failed to start vpnhole: %w", err))
+	}
+	defer func() {
+		if err := c.Stop(); err != nil {
+			log.Println(fmt.Errorf("failed to stop vpnhole: %w", err))
+		}
+	}()
+	log.Printf("vpnhole started: %s", c)
+
+	subscriptions, err := ReadSubscriptions(c.SubscriptionsFilename)
+	if err != nil {
+		log.Fatalln(fmt.Errorf("failed to read subscriptions list: %w", err))
+	}
+
+	for _, blacklistURL := range subscriptions {
+		PrivBlacklist.Subscribe(blacklistURL)
+	}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	go PrivBlacklist.Watch(ctx, time.Minute*10)
+
+	dns.HandleFunc(".", Handler)
+
+	if err = dns.ListenAndServe(c.Addr, "udp", nil); err != nil {
+		log.Println(fmt.Errorf("failed to serve DNS server: %w", err))
+	}
+
+}
diff --git a/subscription.go b/app/vpnhole/sublist.go
similarity index 88%
rename from subscription.go
rename to app/vpnhole/sublist.go
index 4e29e724e711f7e21cacfea6f2bce6e572ec7c05..e4315cdee5511c2adad45a661ca2f16b2e425d8b 100644
--- a/subscription.go
+++ b/app/vpnhole/sublist.go
@@ -6,7 +6,7 @@ import (
 	"os"
 )
 
-func readSubscriptions(filename string) ([]string, error) {
+func ReadSubscriptions(filename string) ([]string, error) {
 	f, err := os.Open(filename)
 	if err != nil {
 		return nil, fmt.Errorf("failed to open: %w", err)
diff --git a/subs.list b/app/vpnhole/subs.list
similarity index 100%
rename from subs.list
rename to app/vpnhole/subs.list
diff --git a/blacklist/blacklist.go b/blacklist/blacklist.go
index dcc88053dac3f546da3854677dc369d8c0b5d760..6a43279d9588a9f3f0c0687107b73a684bc17b3b 100644
--- a/blacklist/blacklist.go
+++ b/blacklist/blacklist.go
@@ -56,7 +56,7 @@ func (b *Blacklist) Watch(ctx context.Context, interval time.Duration) {
 
 				hosts, err := b.updateList(ctx, blacklistURL, sum)
 				if err != nil {
-					log.Println(fmt.Errorf("Failed to update subscription (%s): %w", blacklistURL, err))
+					log.Println(fmt.Errorf("failed to update subscription (%s): %w", blacklistURL, err))
 					return
 				}
 
@@ -98,7 +98,7 @@ func (b *Blacklist) fetch(ctx context.Context, blacklistURL string) ([]string, s
 
 	if resp.StatusCode != http.StatusOK {
 		io.Copy(ioutil.Discard, resp.Body)
-		return nil, "", fmt.Errorf("Unexpected response status code: %d", resp.StatusCode)
+		return nil, "", fmt.Errorf("unexpected response status code: %d", resp.StatusCode)
 	}
 
 	var (
@@ -125,7 +125,7 @@ func (b *Blacklist) fetch(ctx context.Context, blacklistURL string) ([]string, s
 
 	if err = scanner.Err(); err != nil {
 		io.Copy(ioutil.Discard, resp.Body)
-		return nil, "", fmt.Errorf("Failed to scan response body: %w", err)
+		return nil, "", fmt.Errorf("failed to scan response body: %w", err)
 	}
 
 	return hosts, hex.EncodeToString(hasher.Sum(nil)), nil
diff --git a/go.mod b/go.mod
deleted file mode 100644
index a7b3abc06608d53d0767ad5ccfc9641916b4f627..0000000000000000000000000000000000000000
--- a/go.mod
+++ /dev/null
@@ -1,13 +0,0 @@
-module main
-
-go 1.18
-
-require github.com/miekg/dns v1.1.50
-
-require (
-	golang.org/x/mod v0.4.2 // indirect
-	golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 // indirect
-	golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
-	golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
-	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
-)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index b7751ee9b68f84e081057669d416501d0cc373cc..0000000000000000000000000000000000000000
--- a/go.sum
+++ /dev/null
@@ -1,35 +0,0 @@
-github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
-github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8=
-golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
-golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/main.go b/main.go
deleted file mode 100644
index c43a73a6699cace4d868d3eac09204905f5ba264..0000000000000000000000000000000000000000
--- a/main.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package main
-
-import (
-	"context"
-	"flag"
-	"fmt"
-	"log"
-	"net/http"
-	"time"
-
-	"github.com/miekg/dns"
-)
-
-var httpClient = &http.Client{Timeout: 30 * time.Second}
-
-func main() {
-	var (
-		addr                  string
-		subscriptionsFilename string
-	)
-
-	flag.StringVar(&addr, "addr", ":53", "addr")
-	flag.StringVar(&upstream, "upstream", "1.1.1.1:53", "upstream")
-	flag.StringVar(&subscriptionsFilename, "subs", "subs.list", "subscriptions filename")
-	flag.Parse()
-
-	subscriptions, err := readSubscriptions(subscriptionsFilename)
-	if err != nil {
-		log.Fatalln(fmt.Errorf("Failed to read subscriptions list: %w", err))
-	}
-
-	for _, blacklistURL := range subscriptions {
-		privBlacklist.Subscribe(blacklistURL)
-	}
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	go privBlacklist.Watch(ctx, time.Minute*10)
-
-	dns.HandleFunc(".", handler)
-
-	if err = dns.ListenAndServe(addr, "udp", nil); err != nil {
-		log.Println(fmt.Errorf("Failed to serve DNS server: %w", err))
-	}
-}
diff --git a/vpnhole/vpnhole.go b/vpnhole/vpnhole.go
new file mode 100644
index 0000000000000000000000000000000000000000..3acba5f5b333eebcbddb4199dc6f627490b34e54
--- /dev/null
+++ b/vpnhole/vpnhole.go
@@ -0,0 +1,32 @@
+package vpnhole
+
+import (
+	"fmt"
+)
+
+var ErrShutdown = fmt.Errorf("vpnhole was shutdown gracefully")
+
+type vpnholeclient struct {
+	Addr                  string
+	SubscriptionsFilename string
+	Upstream              string
+}
+
+// parse the flags and return the config struct with the values
+func ParseFlags() vpnholeclient {
+	return vpnholeclient{
+		Addr:                  ":53",
+		SubscriptionsFilename: "subs.list",
+		Upstream:              "1.1.1.1:53",
+	}
+}
+
+// start the vpnhole
+func (c *vpnholeclient) Start() error {
+	return nil
+}
+
+// stop the vpnhole
+func (c *vpnholeclient) Stop() error {
+	return nil
+}