How can I show the vertex positions in viewport? I want to show some Info in the viewport something like vertex indices

you can see select a vertex and press N to see vertex position but it's hard.

so I liked to write a script to show the vertex position

I tried to use opengl but text was blurry and I couldn't make what I want.
# import stand alone modules
import blf
import bpy

font_info = {
    &quot;font_id&quot;: 0,
    &quot;handler&quot;: None,
}


def init():
    &quot;&quot;&quot;init function - runs once&quot;&quot;&quot;
    import os
    # Create a new font object, use external ttf file.
    font_path = bpy.path.abspath('//Zeyada.ttf')
    # Store the font indice - to use later.
    if os.path.exists(font_path):
        font_info[&quot;font_id&quot;] = blf.load(font_path)
    else:
        # Default font.
        font_info[&quot;font_id&quot;] = 0

    # set the font drawing routine to run every frame
    font_info[&quot;handler&quot;] = bpy.types.SpaceView3D.draw_handler_add(
        draw_callback_px, (None, None), 'WINDOW', 'POST_VIEW')


def draw_callback_px(self, context):

    &quot;&quot;&quot;Draw on the viewports&quot;&quot;&quot;
    # BLF drawing routine
    font_id = font_info[&quot;font_id&quot;]
    #blf.position(font_id, pos.x, pos.y, pos.z)
    #blf.size(font_id, 100,100)
    #blf.draw(font_id, &quot;Hello World&quot;)

    pos = bpy.context.object.location
    v3d = context.space_data
    rv3d = v3d.region_3d
    pos_text = location_3d_to_region_2d(region, rv3d, context._center)
    
    blf.position(font_id, pos_text[0], pos_text[1], 0)
    blf.size(font_id, 100,100)
    blf.draw(font_id, &quot;Hello World&quot;)


if __name__ == '__main__':
    init()
Well, you are passing no context
(None, None)

but then using some context in draw_callback_px
that is None
you should use POST_PIXEL because it isn't 3d
bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (bpy.context, None), 'WINDOW', 'POST_PIXEL')

you forgot to import location_3d_to_region_2d libraries
import bpy
from bpy_extras.view3d_utils import location_3d_to_region_2d

Go to Window &gt; Open System Console and you will see all the errors
so you can have something to debug what is happening there

convert coordinates from vertex to world-space
Multiply the world matrix by the object-space vector for world space coordinate:
import bpy

ob = bpy.data.objects['Cube']

v = ob.data.vertices[0].co
mat = ob.matrix_world

# Multiply matrix by vertex
loc = mat @ v


import blf
import bpy
from bpy_extras.view3d_utils import location_3d_to_region_2d


def draw_callback_px(context, dummy):
    ob = bpy.data.objects['Cube']

    v = ob.data.vertices[0].co
    mat = ob.matrix_world

    # Multiply matrix by vertex
    pos = mat @ v
    
    v3d = context.space_data
    rv3d = v3d.region_3d
    pos_text = location_3d_to_region_2d(context.region, rv3d, pos)

    blf.position(0, pos_text[0], pos_text[1], 0)
    blf.size(0, 1,1)
    blf.draw(0, str(pos))


bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (bpy.context, None), 'WINDOW', 'POST_PIXEL')

special thanks for @jfranmatheu and @batFINGER