diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml
index f15cbaf..1748219 100644
--- a/.github/workflows/workflow.yaml
+++ b/.github/workflows/workflow.yaml
@@ -5,6 +5,7 @@ on:
       - v*
     branches:
       - master
+      - main
   pull_request:
 
 jobs:
@@ -12,11 +13,11 @@ jobs:
     name: unit-tests
     strategy:
       matrix:
-        go-version: [ 1.17.x, 1.18.x ] # support latest 2 major versions
+        go-version: [ 1.21.x, 1.22.x ] # support latest 2 major versions
         os: [ ubuntu-latest ]
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: Install Go
         uses: actions/setup-go@v5
@@ -37,34 +38,21 @@ jobs:
 
   lint:
     name: lint
-    strategy:
-      matrix:
-        go-version: [ 1.17.x, 1.18.x ] # support latest 2 major versions
-        os: [ ubuntu-latest ]
-    runs-on: ${{ matrix.os }}
+    runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: Install Go
-        uses: actions/setup-go@v3
+        uses: actions/setup-go@v5
         with:
-          go-version: ${{ matrix.go-version }}
+          go-version-file: ./go.mod
+          cache: true # caching and restoring go modules and build outputs
+
+      - name: Check that 'go mod tidy' was called before commit
+        run: go mod tidy && git diff --exit-code
 
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@v3
+        uses: golangci/golangci-lint-action@v4
         with:
-          version: v1.46
-
-          # Optional: working directory, useful for monorepos
-          # working-directory: somedir
-
-          # Optional: golangci-lint command line arguments.
-          # TODO: switch to .golangci.yml
-          args: >
-            --tests=false
-            -E bodyclose -E golint -E rowserrcheck -E gosec -E interfacer
-            -E unconvert -E dupl -E goconst -E gocognit -E goimports -E maligned -E unparam
-            -E dogsled -E prealloc -E gocritic -E wsl -E goprintffuncname
-
-          # Optional: show only new issues if it's a pull request. The default value is `false`.
-          # only-new-issues: true
+          version: v1.56
+          skip-cache: true # cache/restore is done by actions/setup-go step
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..47dafc1
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,111 @@
+linters:
+  # please, do not use `enable-all`: it's deprecated and will be removed soon.
+  # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
+  disable-all: true
+  enable:
+    - errcheck
+    - ineffassign
+    - bodyclose
+    - govet
+    - gosec
+
+    - staticcheck
+    - typecheck
+    - gosimple
+    - prealloc
+    - nolintlint
+
+    - stylecheck
+    - gocritic
+    - revive
+    - gofmt
+    - goimports
+    - lll
+    - nlreturn
+
+    - dogsled
+    - exhaustive
+    - exportloopref
+    - funlen
+    - gochecknoinits
+    - gocognit
+    - goconst
+    - gocyclo
+    - goprintffuncname
+    - misspell
+    - nakedret
+    - rowserrcheck
+    - unconvert
+    - unparam
+    - unused
+
+  # TODO:
+  # - noctx
+  # - depguard
+  # - dupl # skip in tests?
+
+  # disabled:
+  # - asciicheck
+  # - gochecknoglobals
+  # - godot
+  # - godox
+  # - goerr113
+  # - nestif
+  # - testpackage
+  # - wsl
+  # - whitespace
+
+linters-settings:
+  dupl:
+    threshold: 100
+  funlen:
+    lines: 100
+    statements: 50
+  gci:
+    local-prefixes: github.com/vtopc/epoch
+  goconst:
+    min-len: 2
+    min-occurrences: 2
+  gocritic:
+    enabled-tags:
+      - diagnostic
+      - experimental
+      - opinionated
+      - performance
+      - style
+      # - ifElseChain # ERRO Invalid gocritic settings: gocritic [enabled]tag "ifElseChain" doesn't exist
+    disabled-checks:
+      - dupImport # https://github.com/go-critic/go-critic/issues/845
+      - octalLiteral
+      - wrapperFunc
+      - whyNoLint
+  gocyclo:
+    min-complexity: 15
+  goimports:
+    local-prefixes: github.com/vtopc/epoch
+  golint:
+    min-confidence: 0
+  govet:
+    check-shadowing: true
+    #settings:
+    #  printf:
+    #    funcs:
+    #      - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
+    #      - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
+    #      - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
+    #      - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
+  lll:
+    line-length: 140
+  misspell:
+    locale: US
+  nolintlint:
+    allow-unused: false # report any unused nolint directives
+    require-explanation: true # require an explanation for nolint directives
+    require-specific: true # require nolint directives to be specific about which linter is being skipped
+
+issues:
+  # Maximum issues count per one linter. Set to 0 to disable. Default is 50.
+  max-issues-per-linter: 0
+
+  # Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
+  max-same-issues: 50
diff --git a/Makefile b/Makefile
index ea47f74..66b733d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,5 +8,13 @@ test: ## Run unit tests.
 
 .PHONY: deps
 deps: ## Install dependencies.
-	GO111MODULE=on go mod tidy
-	GO111MODULE=on go mod download
+	go mod download
+
+# linter:
+GOLINT = $(GOPATH)/bin/golangci-lint
+$(GOLINT):
+	curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.56.2
+
+.PHONY: lint
+lint: $(GOLINT) ## Run linters.
+	$(GOLINT) run
diff --git a/float_ms.go b/float_ms.go
index 279f9c7..4897a59 100644
--- a/float_ms.go
+++ b/float_ms.go
@@ -9,7 +9,8 @@ import (
 
 // FloatMS - integer part of timestamp represents seconds and fractional - milliseconds since
 // the Epoch(Unix time), e.g.
-//   1136239445.999
+//
+// 1136239445.999
 //
 // Inherits built-in time.Time type, thus has all it methods, but has custom serializer and
 // deserializer(converts float timestamp into built-in time.Time and vice versa).
diff --git a/str_milliseconds.go b/str_milliseconds.go
index 82b1e5f..6b6c91f 100644
--- a/str_milliseconds.go
+++ b/str_milliseconds.go
@@ -20,6 +20,7 @@ func NewStrMilliseconds(t time.Time) StrMilliseconds {
 // MarshalJSON - implements JSON marshaling interface
 func (m StrMilliseconds) MarshalJSON() ([]byte, error) {
 	ms := m.Time.UnixNano() / nsPerMs
+
 	return json.Marshal(strconv.FormatInt(ms, 10))
 }